db.chat.find().pretty().limit(3)
{
"_id" : ObjectId("593921425ccc8150f35e7662"),
"user1" : 1,
"user2" : 2,
"messages" : [
{
"capty" : 'A',
"body" : "hiii 0"
},
{
"capty" : 'B',
"body" : "hiii 1"
},
{
"capty" : 'A',
"body" : "hiii 2"
}
]
}
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user1" : 1,
"user2" : 3,
"messages" : [
{
"capty" : 'A',
"body" : "hiii 0"
},
{
"capty" : 'A',
"body" : "hiii 1"
},
{
"capty" : 'B',
"body" : "hiii 23"
}
]
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user1" : 1,
"user2" : 4,
"messages" : [
{
"capty" : 'A',
"body" : "hiii 0"
},
{
"capty" : 'B',
"body" : "hiii 1"
},
{
"capty" : 'B',
"body" : "hiii 24"
}
]
}
我不是要弄清楚会给出user2列表的查询,以及user1 = 1的主体和消息的最后一个cap =' B'。即输出应该是最后2行。
即可取的输出。
user2:3, "body" : "hiii 23"
user2:4, "body" : "hiii 24"
答案 0 :(得分:0)
这里的主要内容是聚合$slice
以从数组中获取最后一个元素
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
实际上是关注" last"数组条目并测试字段的值。我们可以通过$messages.capty
来回显示数组中的字段,它只返回这些项的数组。如果您想获取最后一个值,那么我们接着$slice
甚至$arrayElemAt
,作为-1
的索引。
此时我们只是"过滤" "文件"哪个与条件不符。最后的$project
阶段获取数组的最后一个元素,检查它是否与条件匹配(它应该是早期阶段),提取"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 ]
}
}}
])
整个事情真的分解为"将可能的文档与查询匹配"然后"用$slice
或$arrayElemAt
"比较并提取最后一个元素。
结果是:
{
"_id" : ObjectId("593921425ccc8150f35e7663"),
"user2" : 3,
"body" : "hiii 23"
}
{
"_id" : ObjectId("593921425ccc8150f35e7664"),
"user2" : 4,
"body" : "hiii 24"
}