Chapter 2: Ticket: Get Comments

I’m having a problem implementing the sorting stage.
I can’t figure out why it’s failing the test
I tested the code in mongo shell and it is sorting the comments by date.

{$match: {_id: ObjectId(id)}},
{$lookup: {from: “comments”,foreignField: “movie_id”,localField: “_id”, as: “comments”}},
{$unwind: ‘$comments’}, {$sort: {“comments.date”: -1}},
{$group: {_id: “$_id”, “sortedComments”: {$push: “$comments”}}}

Your sorted comments are in the field named sortedComments but the requirements ask for a field named comments.

There is a version of $lookup that allows you to $sort within a pipeline. The will allow you to avoid $unwind.

@steevej
I inadvertently left out the last line of code

    {$unwind: '$comments'},
    {$sort: {"comments.date": -1}},
    {$group: {_id: "$_id", "sortedComments": {$push: "$comments"}}},
    {$project: {"comments":"$sortedComments"}}

I will check out the alternative you suggested.

@steevej
Sorry for any confusion.
The updated code works to a point…

If I comment out the sort part it passes test1
If I uncomment the sort part it fails test1 and passes test2

  const pipeline = [
    {
      $match: {
        _id: ObjectId(id)
      }
    },
    {$lookup: {
        from: "comments",
        foreignField: "movie_id",
        localField: "_id",
        as: "comments"
    }},

    {$unwind: '$comments'},
    {$sort: {"comments.date": -1}},
    {$group: {_id: "$_id", "sortedComments": {$push: "$comments"}}},
    {$project: {"comments":"$sortedComments"}}
  ]

Your $project part remove all other fields from the document except _id. So the final form of the document is

{ _id : ObjectId( .... ) , comments : [ { comment_0 } , { comment_1 } ]

So it test expect to have the title of the movie the test will fail since you do not have the title.

You may achieve the renaming of sortedComments to comments with $addFields or $set.

Using $unwind and then group on _id:$_id is some kind of an anti-pattern.

Despite still not the best solution look at https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortArray/ to sort an array within a document. This will allow you to remove the $unwind and $group.

1 Like

@steevej
Thank you… I started looking sortArray but went back to my old code. (that’s me being anal )
I tested it atlas and saw I was only projecting the sorted comments but couldn’t figure out how to add it back to the movies collection.

1 Like

@steevej
I mistakenly sent this as a direct email to you instead of to the forum.

I am getting the following error:
MongoServerError : $sortArray is not allowed or the syntax is incorrect

My code:

{
  $match: {
     _id: ObjectId(id)
   }
},
{
  $lookup:{
      from:  "comments", 
      localField:  "_id", 
      foreignField:  "movie_id", 
      as: "comments" 
      }
}, 
{$sortArray:  {
      input: "$comments", 
      sortBy: {"date": -1}
       }
 } 

The error means that $sortArray is not stage like $match and $lookup.

It is an expression that you could in $project, $set or $addFields stages. It can also be used in other stages.

Thank you!!

I did some more digging into $lookup documentation and I was able to do the sort within the $lookup
using pipeline:
Like this example in the documentation:

  $lookup:
     {
       from: "holidays",
       pipeline: [
          { $match: { year: 2018 } },
          { $project: { _id: 0, date: { name: "$name", date: "$date" } } },
          { $replaceRoot: { newRoot: "$date" } }
       ],
       as: "holidays"
     }
1 Like

I finally figured it out!!
$sortArray works in version 5.2 or higher.
This course is using version 5.0.12!!

Can you please tell the tech guys to upgrade??

Thanks again for all your help!!

1 Like

Sorry that I mislead you with $sortArray.

Hey @steevej
No need to apologize!! I learned a lot about $sortArray.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.