I'm using the following query to fetch one most recent comment for every post in database:
db.comments.aggregate([
{
"$match": {
"post_id": {
"$in": [ObjectId("52c5ce24dca32d32740c1435"), ObjectId("52c5ce24dca32d32740c15ad")]
}
}
},
{
"$sort": {"_id": -1}
},
{
"$group": {
"_id": "$post_id",
"lastComment": {
"$first": "$_id"
}
}
}
])
I expect it to return the whole comment's document but it only returns the _id
field of each document. So what would be the proper way to get all most recent comments as a whole document (or at least include some other fields)?
aggregate() method returns a cursor to the documents produced by the final stage of the aggregation pipeline operation, or if you include the explain option, the document that provides details on the processing of the aggregation operation.
If the pipeline includes the $out operator, aggregate() returns an empty cursor.
aggregate() method always returns Objects no matter what you do and that cannot change. However, that does not mean you cannot put them in an array and return the array in an object.
$unwind treats the sizes field as a single element array if: the field is present, the value is not null, and. the value is not an empty array.
Currently you cannot get the whole comment
document via single $first
operator. But you can include other necessary fields (similar to _id
field) during $group
step:
{
"$group": {
_id: "$post_id",
lastComment: { "$first": "$_id" },
field_1: { "$first": "$field_1" },
field_2: { "$first": "$field_2" },
// ...
field_N: { "$first": "$field_N" }
}
}
According to this JIRA ticket: https://jira.mongodb.org/browse/SERVER-5916, the whole document will be available to return from aggregation operations from 2.5.3 version. It will be possible using new variables: $$ROOT
or $$CURRENT
:
{
"$group": {
_id: "$post_id",
lastComment: { "$first": "$$CURRENT" }
}
}
As suggested, we can do :
{
"$group": {
_id: "$post_id",
lastComment: { "$first": "$$CURRENT" }
}
}
and then do use { '$replaceRoot': { 'newRoot': '$lastComment' } } on any mongodb server 3.4 or above to unwrap object from {lastComment:{actualEntireObj}},{lastComment:{actualEntireObj}}
to {},{}
this way it will get embedded $$ROOT document to the top level and replaces all other fields like _id returning from $group stage of aggregation.
db.collection.aggregate([
{
"$match": {
"post_id": {
"$in": [ObjectId("52c5ce24dca32d32740c1435"), ObjectId("52c5ce24dca32d32740c15ad")]
}
}
},
{
"$sort": { "_id": -1 }
},
{
"$group": {
_id: "$post_id",
lastComment: { "$first": "$$CURRENT" }
}
},
{ '$replaceRoot': { 'newRoot': '$lastComment' } }
])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With