Cara terbaik untuk melakukannya adalah menggunakan kerangka kerja agregasi. Anda perlu $group
dokumen Anda dengan "pengguna" dan kembalikan dokumen terakhir untuk setiap pengguna menggunakan $last
operator akumulator tetapi agar ini berfungsi, Anda memerlukan tahap penyortiran awal menggunakan $sort
operator pipa agregasi. Untuk mengurutkan dokumen, Anda perlu mempertimbangkan bidang "createdAt" dan "user".
Tahap terakhir dalam pipeline adalah $match
tahap di mana Anda hanya memilih dokumen terakhir di mana "isAbandoned" sama dengan true
.
db.students.aggregate([
{ "$sort": { "user": 1, "createdAt": 1 } },
{ "$group": {
"_id": "$user",
"last": { "$last": "$$ROOT" }
}},
{ "$match": { "last.isAbandoned": true } }
])
yang mengembalikan sesuatu seperti ini:
{
"_id" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"last" : {
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}
}
Untuk mendapatkan hasil yang diharapkan, kita perlu menggunakan $replaceRoot
operator pipa mulai dari versi 3.4 untuk mempromosikan dokumen yang disematkan ke tingkat atas
{
$replaceRoot: { newRoot: "$last" }
}
Di versi yang lebih lama, Anda perlu menggunakan $project
operasi pipa agregasi untuk membentuk kembali dokumen kami. Jadi jika kita memperluas pipeline kita dengan tahapan berikut:
{
"$project": {
"_id": "$last._id",
"user": "$last.user",
"studentName": "$last.studentName",
"createdAt": "$last.createdAt",
"isAbandoned": "$last.isAbandoned"
}}
itu menghasilkan keluaran yang diharapkan:
{
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}