これを行う最良の方法は、集約フレームワークを使用することです。 $group
する必要があります 「user」でドキュメントを返し、$last
を使用して各ユーザーの最後のドキュメントを返します アキュムレータ演算子ですが、これを機能させるには、$sort
を使用した予備的な並べ替え段階が必要です。 集約パイプライン演算子。ドキュメントを並べ替えるには、「createdAt」フィールドと「user」フィールドの両方を考慮する必要があります。
パイプラインの最後の段階は$match
です 「isAbandoned」がtrue
に等しい最後のドキュメントのみを選択するステージ 。
db.students.aggregate([
{ "$sort": { "user": 1, "createdAt": 1 } },
{ "$group": {
"_id": "$user",
"last": { "$last": "$$ROOT" }
}},
{ "$match": { "last.isAbandoned": true } }
])
これは次のようなものを返します:
{
"_id" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"last" : {
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}
}
期待どおりの結果を得るには、$replaceRoot
を使用する必要があります 埋め込まれたドキュメントをトップレベルにプロモートするためのバージョン3.4から始まるパイプラインオペレーター
{
$replaceRoot: { newRoot: "$last" }
}
古いバージョンでは、$project
を使用する必要があります ドキュメントを再形成するための集約パイプライン操作。したがって、パイプラインを次の段階で拡張すると、次のようになります。
{
"$project": {
"_id": "$last._id",
"user": "$last.user",
"studentName": "$last.studentName",
"createdAt": "$last.createdAt",
"isAbandoned": "$last.isAbandoned"
}}
期待される出力を生成します:
{
"_id" : ObjectId("56cee51503b7cb7b0eda9c4c"),
"user" : ObjectId("56c85244bd5f92cd78ae4bc1"),
"studentName" : "Rajeev",
"createdAt" : ISODate("2016-02-25T11:27:17.281Z"),
"isAbandoned" : true
}