Nejlepším způsobem, jak toho dosáhnout, je použití agregačního rámce. Musíte $group
vaše dokumenty podle "uživatele" a vraťte poslední dokument pro každého uživatele pomocí $last
operátor akumulátoru, ale aby to fungovalo, potřebujete fázi předběžného třídění pomocí $sort
provozovatel agregačního potrubí. Chcete-li seřadit dokumenty, musíte vzít v úvahu pole „vytvořenoAt“ i pole „uživatel“.
Poslední fází procesu je $match
fázi, kdy vyberete pouze ty poslední dokumenty, kde se "isAbandoned" rovná true
.
db.students.aggregate([
{ "$sort": { "user": 1, "createdAt": 1 } },
{ "$group": {
"_id": "$user",
"last": { "$last": "$$ROOT" }
}},
{ "$match": { "last.isAbandoned": true } }
])
který vrátí něco takového:
{
"_id" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"last" : {
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}
}
Abychom získali očekávaný výsledek, musíme použít $replaceRoot
operátor kanálu od verze 3.4 k povýšení vloženého dokumentu na nejvyšší úroveň
{
$replaceRoot: { newRoot: "$last" }
}
Ve starší verzi je potřeba použít $project
operace agregačního kanálu za účelem přetvoření našich dokumentů. Pokud tedy rozšíříme naše potrubí o následující fázi:
{
"$project": {
"_id": "$last._id",
"user": "$last.user",
"studentName": "$last.studentName",
"createdAt": "$last.createdAt",
"isAbandoned": "$last.isAbandoned"
}}
vytváří očekávaný výstup:
{
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}