0

我有具有这种结构的文件

x = {
       "scalar": 1,
       "array": [
          {"key": 1, "value": 2},
          {"key": 2, "value": 3},
       ],
       "array2": [
          {"key": 1, "value": 2},
          {"key": 2, "value": 3},
       ],
    }

y = {
    "scalar": 2,
    "array": [
        {"key": 1, "value": 3},
        {"key": 3, "value": 0},
    ],
    "array2": [
        {"key": 1, "value": 3},
        {"key": 3, "value": 0},
    ],
}

我试图找到的最终结果是这样的

{
    "scalar": 3, # SUM of scalar
    "array": [
        {"key": 1, "value": 5},  # SUM by key = 1
        {"key": 2, "value": 3},
        {"key": 3, "value": 0},
    ],
    "array2": [
        {"key": 1, "value": 5},  # SUM by key = 1
        {"key": 2, "value": 3},
        {"key": 3, "value": 0},
    ],
}

我试过使用双倍$unwind然后推过去。我正在考虑使用$reduce来获得最终结果

4

1 回答 1

0

询问

  • 一种方法是通过方面,你想要 3 个分组,而方面可以做到这一点,比如分成 3 个单独的部分,不要混合展开,我认为这是最简单的方法

测试代码在这里

db.collection.aggregate([
  {
    "$facet": {
      "scalar": [
        {
          "$project": {
            "scalar": 1
          }
        },
        {
          "$group": {
            "_id": null,
            "sum": {
              "$sum": "$scalar"
            }
          }
        },
        {
          "$unset": [
            "_id"
          ]
        }
      ],
      "array": [
        {
          "$project": {
            "array": 1
          }
        },
        {
          "$unwind": {
            "path": "$array"
          }
        },
        {
          "$group": {
            "_id": "$array.key",
            "sum": {
              "$sum": "$array.value"
            }
          }
        },
        {
          "$project": {
            "_id": 0,
            "key": "$_id",
            "value": "$sum"
          }
        }
      ],
      "array2": [
        {
          "$project": {
            "array2": 1
          }
        },
        {
          "$unwind": {
            "path": "$array2"
          }
        },
        {
          "$group": {
            "_id": "$array2.key",
            "sum": {
              "$sum": "$array2.value"
            }
          }
        },
        {
          "$project": {
            "_id": 0,
            "key": "$_id",
            "value": "$sum"
          }
        }
      ]
    }
  },
  {
    "$set": {
      "scalar": {
        "$arrayElemAt": [
          "$scalar.sum",
          0
        ]
      }
    }
  }
])

另一种选择是展开两个数组,但随后展开和组将混合在一起,我认为这让事情变得复杂。

我认为也$reduce不能用于 MongoDB 中的分组,因为我们无法构造动态路径。

如果 group-reduce 并且有这个数据(key=key value=value)

{"1" : 5 , "2" : 3}

我们看看{"key" 1, "value" : 5}如何检查上述数据是否包含 1 作为键?我们不能构造动态路径,比如$$this.1. 只有这样才能将其转换为数组并返回到非常慢的对象。

于 2021-10-05T18:25:13.490 回答