Der beste Weg, dies zu tun, ist die Verwendung des Aggregation Frameworks. Sie müssen $group
Ihre Dokumente nach "Benutzer" und geben Sie das letzte Dokument für jeden Benutzer mit $last
zurück Akkumulator-Operator, aber damit das funktioniert, benötigen Sie eine Vorsortierung mit dem $sort
Aggregation-Pipeline-Betreiber. Um Ihre Dokumente zu sortieren, müssen Sie sowohl das Feld „createdAt“ als auch das Feld „user“ berücksichtigen.
Die letzte Stufe in der Pipeline ist $match
Phase, in der Sie nur die letzten Dokumente auswählen, bei denen "isAbandoned" gleich true
ist .
db.students.aggregate([
{ "$sort": { "user": 1, "createdAt": 1 } },
{ "$group": {
"_id": "$user",
"last": { "$last": "$$ROOT" }
}},
{ "$match": { "last.isAbandoned": true } }
])
was so etwas zurückgibt:
{
"_id" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"last" : {
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}
}
Um das erwartete Ergebnis zu erhalten, müssen wir $replaceRoot
verwenden Pipeline-Operator ab Version 3.4, um das eingebettete Dokument auf die oberste Ebene zu befördern
{
$replaceRoot: { newRoot: "$last" }
}
In älteren Versionen müssen Sie das $project
verwenden Aggregations-Pipeline-Betrieb, um unsere Dokumente umzugestalten. Wenn wir also unsere Pipeline um die folgende Stufe erweitern:
{
"$project": {
"_id": "$last._id",
"user": "$last.user",
"studentName": "$last.studentName",
"createdAt": "$last.createdAt",
"isAbandoned": "$last.isAbandoned"
}}
es erzeugt die erwartete Ausgabe:
{
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}