通过聚合中的索引投影嵌套数组字段值
Posted
技术标签:
【中文标题】通过聚合中的索引投影嵌套数组字段值【英文标题】:Project nested array field values by their indexes in aggregation 【发布时间】:2016-07-01 14:52:07 【问题描述】:我正在 MongoDB 中进行聚合,它的 $project
阶段应该有一个数组字段投影。但我无法通过索引访问数组字段:
//projection stage
$project:
'foo' : '$ifNull' : ['$bar.0.baz.0.qux', '*']
这会将 foo
设置为一个空的 array 。 bar 是一个多维数组字段。我的 MongoDB 版本是 3.2 。如果没有$unwind/$group
旧的繁重解决方案的麻烦,我该怎么办?
感谢您的帮助。
【问题讨论】:
【参考方案1】:使用$slice
、$map
和$arrayElemAt
:
"$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
【讨论】:
谢谢哥们。我试图理解这个解决方案。它似乎运作良好。我会尽快检查你的答案。遗憾的是,他们没有用简单的 javascript 对象访问模式替换这个巨大的代码 sn-p。希望在未来的版本中看到这一点。【参考方案2】:将多个 $project 阶段与带有临时字段的 $arrayElemAt 运算符一起使用。
$project:"tmp": $arrayElemAt:["$bar",0],
$project:"tmp2": $arrayElemAt:["$tmp.baz",0]
你的价值是 $tmp2.qux。
【讨论】:
以上是关于通过聚合中的索引投影嵌套数组字段值的主要内容,如果未能解决你的问题,请参考以下文章