Cách tốt nhất để làm điều này là sử dụng khung tổng hợp. Bạn cần $group
tài liệu của bạn theo "người dùng" và trả lại tài liệu cuối cùng cho mỗi người dùng bằng $last
toán tử tích lũy nhưng để điều này hoạt động, bạn cần một giai đoạn phân loại sơ bộ bằng cách sử dụng $sort
nhà điều hành đường ống tổng hợp. Để sắp xếp tài liệu của mình, bạn cần xem xét cả trường "createAt" và trường "người dùng".
Giai đoạn cuối cùng trong quy trình là $match
giai đoạn mà bạn chỉ chọn những tài liệu cuối cùng trong đó "isAbandoned" bằng true
.
db.students.aggregate([
{ "$sort": { "user": 1, "createdAt": 1 } },
{ "$group": {
"_id": "$user",
"last": { "$last": "$$ROOT" }
}},
{ "$match": { "last.isAbandoned": true } }
])
trả về một cái gì đó như thế này:
{
"_id" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"last" : {
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}
}
Để có được kết quả mong đợi, chúng ta cần sử dụng $replaceRoot
nhà điều hành đường ống bắt đầu từ Verion 3.4 để quảng bá tài liệu nhúng lên cấp cao nhất
{
$replaceRoot: { newRoot: "$last" }
}
Trong phiên bản cũ hơn, bạn cần sử dụng $project
hoạt động đường ống tổng hợp để định hình lại tài liệu của chúng tôi. Vì vậy, nếu chúng tôi mở rộng quy trình của mình với giai đoạn sau:
{
"$project": {
"_id": "$last._id",
"user": "$last.user",
"studentName": "$last.studentName",
"createdAt": "$last.createdAt",
"isAbandoned": "$last.isAbandoned"
}}
nó tạo ra sản lượng mong đợi:
{
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}