MongoError: A pipeline stage specification object must contain exactly one field

const pipeline = [
        {
          $match: {
            _id: ObjectId(id)
          },
          $lookup: {
            from: 'comments',
            let: {'id':'$_id'},
            pipeline:[{$match:{$expr:{$eq:['$movie_id','$$id']}}},{ $sort: { 'date': -1 } }],
            as: 'comments',
          },
        }
      ]

Whats the error?

At first sight, without the exact error message you are getting, my guess would bee that you are missing a closing brace and an opening brace before $lookup.

1 Like

Error:
MongoError: A pipeline stage specification object must contain exactly one field.

I am getting the error mentioned above. Nothing to do with the braces, I tested.

post a screenshot of running the pipeline with the proposed modification

Hello,

as: ‘comments’,
}, <===

Extra comma?

1 Like

Getting this error. Please help

Not working yet. Tried multiple syntax, copied the code working in compass, still getting the same error.

Would you mind posting the whole block of code for the getMovieByID function. The screen grab/image.

The error is with your pipeline. If you do not share your pipeline there is no way we can find what is wrong with it.

1 Like
static async getMovieByID(id) {

    try {

      /**

      Ticket: Get Comments

      Given a movie ID, build an Aggregation Pipeline to retrieve the comments

      matching that movie's ID.

      The $match stage is already completed. You will need to add a $lookup

      stage that searches the `comments` collection for the correct comments.

      */

      // TODO Ticket: Get Comments

      // Implement the required pipeline.

      const pipeline = [

        {

          $match: {

            _id: ObjectId(id)

          },

          $lookup: {

            from: 'comments',

            let: {'id':'$_id'},

            pipeline:[{$match:{$expr:{$eq:['$movie_id','$$id']}}},{ $sort: { 'date': -1 } }],

            as: 'comments',

          }

        }

        

      ]

      return await movies.aggregate(pipeline).next()

    } catch (e) {
console.error(`Something went wrong in getMovieByID: ${e}`)

      throw e

    }

  }

}

Whole code. could not find the error

@Debayan_Ghosh

Braces are wrong. I copied your code into my version and made these changes : -

const pipeline = [
{

  $match: {

    _id: ObjectId(id)
      } <=== Missing 
  },
  {  <=== Missing 
     $lookup: {
         from: 'comments',
         let: {'id':'$_id'},
         pipeline:[
            { $match:
                {$expr:
                    {$eq:['$movie_id','$$id']}
                 }
            },
            { $sort: { 'date': -1 } 
            }
         ], 
         as: 'comments'   ,  <=== extra comment unnecessary
  }
}

]

image

My only tip I would have going forward is use a dev tool which has a bracket matcher/colourizer, since Mongo is a pain with brackets.

1 Like

You are still have the same issue

despite

Try with my proposed modification which would give

pipeline = [

    {

      $match: {

        _id: ObjectId(id)

      }},{

      $lookup: {

        from: 'comments',

        let: {'id':'$_id'},

        pipeline:[{$match:{$expr:{$eq:['$movie_id','$$id']}}},{ $sort: { 'date': -1 } }],

        as: 'comments',

      }

    }
]
1 Like

You mean JSON? B-)

We observe braces issues more often with Mongo as it is used intensively.

It just gives me heartburn :slight_smile:

1 Like

Me too. That’s why I seldom write big monolithic aggregations. I use variables. For example, for the above I would write:

match_movie = { "$match" : {  "_id" : ObjectId(id) } } ;
match_comments = { "$match" : { "$expr" : { "$eq" : [ "$movie_id" , "$$id" ] } } } ;
sort_comments = { "$sort" : { "date" : -1 } } ;
comments_pipeline = [ match_comments , sort_comments ] ;
lookup_comments = {
  "$lookup" :
  {
    "from" : "comments" ,
    "let" : { "id" : "$_id" } ,
    "pipeline" : comments_pipeline ,
    "as" : "comments" ,
  }
} ;
pipeline = [ match_movie , lookup_comments ] ;

Easier to write, without JSON braces and brackets heartburn, because there is only few per lines or blocks. And the indentation level is smaller.

Easier to understand because the long variable names serve as documentation.

Easier to modify as you edit a smaller part of the code. Specially true with the shell as you simply edit the variable and use the command line history to reevaluate the pipeline.

3 Likes

To be honest, I am coming around to this way of thinking.

The ease I find it getting the commands wrong, or bracketed incorrectly, is frustrating. I do hope that as my comfort with the syntax improves, then life will improve :slight_smile: Otherwise it back to writing openedge code.

Hi @NeilM, :wave:
You can also tryout our Atlas Aggregation Builder to create these pipelines. The pipeline builder provides an easy way to export your pipeline to execute in a driver.

I hope this helps and will surely reduce the chances of making typos.

In case you have any doubts, please feel free to reach out to us.

Thanks and Regards.
Sourabh Bagrecha,
Curriculum Services Engineer

1 Like