ここでの主なものは、集約 $ slave
配列から最後の要素を取得するには、
db.chat.aggregate([
{ "$match": { "user1": 1, "messages.capty": "B" } },
{ "$redact": {
"$cond": {
"if": {
"$eq": [ { "$slice": [ "$messages.capty", -1 ] }, ["B"] ]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"user2": 1,
"body": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": { "$slice": [ "$messages",-1 ] },
"as": "m",
"cond": { "$eq": [ "$$m.capty", "B" ] }
}
},
"as": "m",
"in": "$$m.body"
}},
0
]
}
}}
])
私は実際、 $projectで「非常に安全」です。
$ filter
を使用してステージングする
しかし、それはすべて基本的に同じです。
最初にクエリでドキュメントが選択されます。現時点では、配列の最後の要素に「のみ」一致するとは言えませんが、配列に条件がまったくないドキュメントをフィルタリングする必要があります。
$ redact
「最後の」配列エントリを調べてフィールドの値をテストする実際のものです。 $ messages.capty
によって、配列のフィールドだけを表記できます。 これらのアイテムの配列のみを返します。次に、 $ slave
または、 $ arrayElemAt
-1
のインデックスである最後の値を取得する場合 。
この時点では、条件に一致しない「ドキュメント」のみを「フィルタリング」しました。最後の $ project
stageは配列の最後の要素を取得し、それが条件に一致することを確認し(前のステージで必要)、 "body"
の値を抽出します。 単一の配列コンテンツを単なる値に変換します。
代わりに、「注意」を放棄して、 $ redact
以降の最後の配列要素を取得することもできます。 その仕事をするべきだった:
db.chat.aggregate([
{ "$match": { "user1": 1, "messages.capty": "B" } },
{ "$redact": {
"$cond": {
"if": {
"$eq": [ { "$arrayElemAt": [ "$messages.capty", -1 ] }, "B" ]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"user2": 1,
"body": {
"$arrayElemAt": [ "$messages.body", -1 ]
}
}}
])
全体は実際には「可能なに一致する」に分解されます クエリを使用してドキュメントを作成し、次に「最後の要素を<と比較して抽出します。コード>$スライスコード>
または $ arrayElemAt
"。
結果は次のとおりです。
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}