Mongodb聚合$ slice以从嵌套数组中获取精确位置的元素

时间:2015-11-30 22:36:18

标签: mongodb mongodb-query slice aggregation-framework

我想从嵌套数组中检索一个值,它存在于数组中的确切位置。

我想通过为名称执行$ 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。

1 个答案:

答案 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还能够投射数组索引,这对于其他目的很方便,但其他运算符对于此特定情况比该功能更有用。

所以对于我的钱,我会等到你有这个功能可以将它集成到聚合管道中,或者至少重新考虑为什么你认为你需要它并可能围绕它进行设计。