【问题标题】: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 旧的繁重解决方案的麻烦,我该怎么办?

感谢您的帮助。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      • 2020-09-25
      • 1970-01-01
      • 2021-03-07
      相关资源
      最近更新 更多