gope153
gope153

Reputation: 85

Mongoose Mongodb sorting and limiting query of subdocuments

I've got the following design Schema:

 {
      participants: [String],
      conversations: [{
          date: Date
          messages: [String]
      }]
 }

Now i want to get the 6 newest converations. I have tried a lot but i can't seem to find the solution. I can sort by subdocuments, but at the end if 1 document has the 6 newest conversations the query will end up giving me this one document plus 5 others. I woud like to get an array like this at the end of the query or be able to get this particular information:

[{date:'Adate', messages:[]},{date:'Adate2',messages:[]}]

Thanks for your help!

Upvotes: 0

Views: 951

Answers (1)

Yathish Manjunath
Yathish Manjunath

Reputation: 2029

Actually this is not possible with the single query if you are a using a mongoDB version LESS than 3.1.6.

$Slice is supported in aggregation pipeline in the mongoDB version 3.1.6 and above

If your mongoDB version is below 3.1.6, then you can try the below piece of code :

db.collection.aggregate([
{ $unwind : "conversations"},
{ $sort : {_id : 1, conversations.date : -1}},
{ $group: { _id : "$_id"} , conversations : { $push : "$conversations"}, participants : {$first : "$participants"} },
{ $project :  { _id : 1, conversations : 1, participants : 1 } }
]).forEach( function(doc)
                { 

                    if( doc.conversations.length > 6)
                    {
                        var count = doc.conversations.length - 6;
                        doc.conversations.splice(6, count );
                    }
                }
            )

There is a similar question on the StackOverflow for the version below 3.1.6, Please check the link.

For the mongoDb Version 3.1.6 and above, you can use $Slice in aggregation pipeline to limit the contents of array.

Try the below code :

db.collection.aggregate([
{ $unwind : "conversations"},
{ $sort : {_id : 1, conversations.date : -1}},
{ $group: { _id : "$_id"} , conversations : { $push : "$conversations"}, participants : {$first : "$participants"} },
{ $project :  
                { 
                    _id : 1, 
                    participants : 1, 
                    newconversations : 
                                        { 
                                            conversations : { $slice : 6 } 
                                        } 
                } 
}
])

Upvotes: 3

Related Questions