我想从嵌套数组中检索一个值,它存在于数组中的确切位置。
我想通过为名称执行$ slice [0,1],然后为值执行$ slice [1,1]来创建名称值对。< / p>
在我尝试使用聚合之前,我想在嵌套数组中尝试查找。我可以在文档中的单个深度数组上执行我想要的操作,如下所示:
{
"_id" : ObjectId("565cc5261506995581569439"),
"a" : [
4,
2,
8,
71,
21
]
}
我应用以下内容: db.getCollection('anothertest')。find({},{_ id:0,a:{$ slice:[0,1]}}) 我得到了:
{
"a" : [
4
]
}
太棒了。但是,如果我想要$ slice [0,1]的数组位于 objectRawOriginData.Reports.Rows.Rows.Cells 的文档中怎么办?
如果我可以首先找到FIND,那么我想将其应用为AGGREGATE。
答案 0 :(得分:9)
你最好的选择,特别是如果你的应用程序还没有准备好发布,那就是推迟到MongoDB 3.2进行部署,或至少在此期间开始与候选版本合作。主要原因是&#34;投影&#34; $slice
不适用于聚合框架,也不适用于其他形式的数组匹配投影。但这已经针对即将发布的版本进行了解决。
这将为您提供几个新的运算符,$slice
甚至$arrayElemAt
,可用于按聚合管道中的位置寻址数组元素。
或者:
db.getCollection('anothertest').aggregate([
{ "$project": {
"_id": 0,
"a": { "$slice": ["$a",0,1] }
}}
])
返回熟悉的内容:
{ "a" : [ 4 ] }
或者:
db.getCollection('anothertest').aggregate([
{ "$project": {
"_id": 0,
"a": { "$arrayElemAt": ["$a", 0] }
}}
])
这只是元素而不是数组:
{ "a" : 4 }
除了发布候选表单之外的版本之外,当前可用的运算符使得#34;第一个&#34;数组的元素:
db.getCollection('anothertest').aggregate([
{ "$unwind": "$a" },
{ "$group": {
"_id": "$_id",
"a": { "$first": "$a" }
}}
])
在$first
之后使用$unwind
运算符。但是获得另一个索引位置变得非常迭代:
db.getCollection('anothertest').aggregate([
{ "$unwind": "$a" },
// Keeps the first element
{ "$group": {
"_id": "$_id",
"first": { "$first": "$a" },
"a": { "$push": "$a" }
}},
{ "$unwind": "$a" },
// Removes the first element
{ "$redact": {
"$cond": {
"if": { "$ne": [ "$first", "$a" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
// Top is now the second element
{ "$group": {
"_id": "$_id",
"second": { "$first": "$a" }
}}
])
等等,还有很多处理来改变它来处理可能比&#34; nth&#34;更短的数组。你正在寻找的元素。所以&#34;可能&#34;,但丑陋且不具备表现力。
同时注意到这不是真的&#34;使用&#34;索引位置&#34;,并且纯粹匹配值。因此,除非每个数组元素都有另一个唯一标识符,否则很容易删除重复的值。未来$unwind
还能够投射数组索引,这对于其他目的很方便,但其他运算符对于此特定情况比该功能更有用。
所以对于我的钱,我会等到你有这个功能可以将它集成到聚合管道中,或者至少重新考虑为什么你认为你需要它并可能围绕它进行设计。