I m actually having trouble when dealing with MongoDb.
I need to :
You can always use $$ROOT to return the whole document on the grouping boundary:
db.collection.aggregate([
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}}
])
Or with direct sort control rather than the natural order:
db.collection.aggregate([
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}}
])
But note that the $group
pipeline does not guarantee a retained document order, so if you need that then you $sort
again:
db.collection.aggregate([
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": "$zone._id",
"doc": { "$last": "$$ROOT" }
}},
{ "$sort": { "doc._id": 1 } }
])
In all cases the alterate to $$ROOT
is simply to declare $last explicitly for each field you want from the document. By contrast the $max operator applies only to the specified field, so this is generally not of use to you when you want documents from the grouping boundary as $last
does.
Considering the "last" example there and also removing the appropriate data from your examples then I get:
{
"_id" : "55cb5bb42d191d2022c5c266",
"doc" : {
"_id" : "55d5a01f9f58d2cc0eb79f5d",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
}
},
{
"_id" : "55cb5bb42d191d2022c5c278",
"doc" : {
"_id" : "55d5a01f9f58d2cc0eb79f5e",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c278",
"zoneName" : "Other zone"
},
"actif" : true
}
}
Altered input is this:
{
"_id" : "55d5a01f9f58d2cc0eb79f5d",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
},
{
"_id" : "55d59f129f58d2cc0eb79f5c",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c266",
"zoneName" : "Syphon 1"
},
"actif" : true
},
{
"_id" : "55d5a01f9f58d2cc0eb79f5e",
"zone" : {
"_id" : "55cb5bb42d191d2022c5c278",
"zoneName" : "Other zone"
},
"actif" : true
}
Not bothering with correct ObjectId
values in case as the hex string values are lexical just as the internal sort of an ObjectId
would be anyway.
Which are the "last" documents for each provided zone._id
value from the collection, ordered by the original document _id
value given.
$last
gives you the value of the last document which is processed by your grouping. You can not predict the order in which documents are processed, unless you sort the documents. So you don't get the results you expect.
Try adding a $sort stage before your $group stage to get the documents in ascending date order:
db.collection.aggregate(
[
{ $sort: {
"control_date":1
}
},
{
$group:
{
_id: "$zone._id",
lastRegistered: { $last: "$_id" },
zoneName:"$zone.zoneName",
control_id:"$_id",
actif:"$actif",
}
}
]
)