我在 MongoDB 中进行聚合,它应该在$project
阶段进行数组字段投影。但我无法通过索引访问数组字段:
{//projection stage
$project: {
'foo' : { '$ifNull' : ['$bar.0.baz.0.qux', '*'] }
}
}
这会将foo
设置为空数组。 bar是一个多维数组字段。我的MongoDB版本是3.2。如果没有$unwind/$group
旧的沉重解决方案的麻烦,我能做些什么呢?
感谢您的帮助。
答案 0 :(得分:4)
{ "$project": {
"foo": {
"$ifNull": [
{ "$arrayElemAt": [
{ "$map": {
"input": { "$slice": [
{ "$map": {
"input": { "$slice": [ "$bar", 0, 1 ] },
"as": "el",
"in": "$$el.baz"
}},
0, 1
]},
"as": "el",
"in": { "$arrayElemAt": [ "$$el.qux", 0 ] }
}},
0
]},
"*"
]
}
}}
因此内部$map
运算符允许您只选择每个数组中的特定字段,您可以$slice
在所需位置返回该元素。即0,1
是零索引,只是一个元素。
对于最终生成的数组,您只需使用$arrayElemAt
并检索索引元素,将其转换为单个值。
当然,$ifNull
测试可能需要更多地参与,具体取决于您的结构,就好像它不一致,那么您可能需要检查每个$map
输入并交换结果相应
但一般过程是:
$map
获取字段$slice
从$map
$arrayElemAt
关于最终的数组结果。在这样的事情上:
db.foo.insert({
"bar": [
{
"baz": [
{ "qux": 2 },
{ "qux": 5 }
]
},
{
"baz": [
{ "qux": 3 },
{ "qux": 4 }
]
}
]
})
产地:
{ "_id" : ObjectId("56e8c6b8ff2a05c0da90b31e"), "foo" : 2 }
答案 1 :(得分:1)
将$ arrayElemAt运算符与临时字段一起使用多个$ project阶段。
{$project:{"tmp": {$arrayElemAt:["$bar",0]}}},
{$project:{"tmp2": {$arrayElemAt:["$tmp.baz",0]}}}
比你的价值是$ tmp2.qux。