Reputation: 85
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
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