用MongodB编写聚合查询

时间:2020-08-24 18:53:57

标签: mongodb mongodb-query aggregation-framework

这是我的示例文档结构,例如

{
    "my_object": {
        "1": {
            "seq": "1",
            "time": "xyz",
        },
        "2": {
            "seq": "2",
            "time": "abc",
            "sub_aray": {
                "0": {
                    "value": 10
                },
                "1": {
                    "value": 10
                },
                "2": {
                    "value": -10
                }
            }
        }
    }
}

所以我要实现的是,所有sub_array的值之和(如果存在),如果未找到sub_array,则将其默认为0

{"seq" : "1", "sub_array" : 0},
{"seq" : "2", "sub_array" : 10}

我的Mongo版本是3.4.6,我正在使用PyMongo作为驱动程序。

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作

playground

db.collection.aggregate([
  {
    $project: {
      "array": { //To remove dynamic keys - 1,2,etc
        "$objectToArray": "$my_object"
      }
    }
  },
  {//reshaping array
    "$unwind": "$array"
  },
  {
    $project: {//reshaping sub array to access via a static name
      "k": {
        "$objectToArray": "$array.v.sub_aray"
      },
      "seq": "$array.v.seq"
    }
  },
  {
    "$project": {//actual logic, output structure
      "sub_array": {
        $sum: "$k.v.value"
      },
      "_id": 0,
      "seq": 1
    }
  }
])

答案 1 :(得分:1)

技巧部分是使用$objectToArray运算符来迭代my_object项。

db.collection.aggregate([
  {
    "$project": {
      "my_object": {
        "$map": {
          input: {
            "$objectToArray": "$my_object"
          },
          as: "obj",
          in: {
            seq: "$$obj.v.seq",
            sub_array: {
              $sum: {
                $map: {
                  input: {
                    "$objectToArray": "$$obj.v.sub_aray"
                  },
                  as: "sub",
                  in: "$$sub.v.value"
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$unwind": "$my_object"
  },
  {
    "$replaceRoot": {
      "newRoot": "$my_object"
    }
  }
])

MongoPlayground