De beste manier om dit te doen is door gebruik te maken van het aggregatieraamwerk. Je moet $group
uw documenten door "gebruiker" en retourneer het laatste document voor elke gebruiker met behulp van de $last
accumulator-operator, maar om dit te laten werken, hebt u een voorbereidende sorteerfase nodig met behulp van de $sort
aggregatie pijpleiding operator. Om uw documenten te sorteren, moet u rekening houden met zowel het veld "createdAt" als het veld "user".
De laatste fase in de pijplijn is de $match
fase waarin u alleen die laatste documenten selecteert waarbij "isAbandoned" gelijk is aan true
.
db.students.aggregate([
{ "$sort": { "user": 1, "createdAt": 1 } },
{ "$group": {
"_id": "$user",
"last": { "$last": "$$ROOT" }
}},
{ "$match": { "last.isAbandoned": true } }
])
wat zoiets als dit teruggeeft:
{
"_id" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"last" : {
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}
}
Om het verwachte resultaat te krijgen, moeten we de $replaceRoot
. gebruiken pijpleidingbeheerder vanaf versie 3.4 om het ingesloten document naar het hoogste niveau te promoten
{
$replaceRoot: { newRoot: "$last" }
}
In een oudere versie moet je de $project
. gebruiken aggregatiepijplijnbewerking om onze documenten opnieuw vorm te geven. Dus als we onze pijplijn uitbreiden met de volgende fase:
{
"$project": {
"_id": "$last._id",
"user": "$last.user",
"studentName": "$last.studentName",
"createdAt": "$last.createdAt",
"isAbandoned": "$last.isAbandoned"
}}
het produceert de verwachte output:
{
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}