【问题标题】:Compare and add two array inside nested arrays在嵌套数组中比较并添加两个数组
【发布时间】:2019-11-26 07:02:17
【问题描述】:

我的文档中有以下数组

  {
    items: [
      ["Tax", 10, 20, 30],
      ["FX Adjustments", 10, 20, 30],
      ["Tax", 10, 20, 30],
      ["FX Adjustments", 10, 20, 30]
    ]
  }

我需要将TaxTaxFX AdjustmentsFX Adjustments 结合起来。

我需要的输出

  {
    items: [
      ["Tax", 20, 40, 60],
      ["FX Adjustments", 20, 40, 60]
    ]
  }

我试过了,但没有成功

db.collection.aggregate([
  {
    $project: {
      items: {
        $reduce: {
          input: "$items",
          initialValue: [],
          in: {
            $cond: [
            ]
          }
        }
      }
    }
  }
])

请帮助解决这个问题

谢谢!!!

【问题讨论】:

    标签: node.js mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您需要从 $unwind 开始,然后是 $group 的第一个数组元素 ($arrayElemAt)。然后你可以像你尝试的那样运行$reduce,但由于你的数组是多维的,你需要用$map 包装它来表示索引。要取回原始数据格式,您可以按null 分组并使用$concatArrays 将分组_id 作为第一个数组元素:

    db.collection.aggregate([
        {
            $unwind: "$items"
        },
        {
            $group: {
                _id: { $arrayElemAt: [ "$items", 0 ] },
                values: { $push: { $slice: [ "$items", 1, { $size: "$items" } ] } }
            }
        },
        {
            $project: {
                _id: 1,
                values: {
                    $map: {
                        input: { $range: [ 0, { $size: { $arrayElemAt: [ "$values", 0 ] } } ] },
                        as: "index",
                        in: {
                            $reduce: {
                                input: "$values",
                                initialValue: 0,
                                in: { $add: [ "$$value", { $arrayElemAt: [ "$$this", "$$index" ] } ] }
                            }
                        }
                    }
                }
            }
        },
        {
            $group: {
                _id: null,
                items: { $push: { $concatArrays: [ [ "$_id" ], "$values" ] } }
            }
        }
    ])
    

    Mongo Playground

    【讨论】:

    • 可以不用$unwind...使用$reduce吗?
    • @Profer 理论上是的,但是代码看起来很容易读 IMO - 您可以尝试使用 $let$arrayElemAt
    • 谢谢,但如果你能这样告诉我...我很容易理解...顺便说一句,什么是 IMO?
    • IMO = 在我看来
    【解决方案2】:

    试试下面的聚合管道

    collectionName.aggregate([
      {
        $unwind: "$items"
      },
      {
        $group: {
          _id: {
            $arrayElemAt: [
              "$items",
              0
            ]
          },
          sum1: {
            $sum: {
              $arrayElemAt: [
                "$items",
                1
              ]
            }
          },
          sum2: {
            $sum: {
              $arrayElemAt: [
                "$items",
                2
              ]
            }
          },
          sum3: {
            $sum: {
              $arrayElemAt: [
                "$items",
                3
              ]
            }
          }
        }
      },
      {
        $project: {
          _id: null,
          items: {
            $map: {
              input: {
                $objectToArray: "$$ROOT"
              },
              as: "item",
              in: "$$item.v"
            }
          }
        }
      },
      {
        $group: {
          _id: null,
          items: {
            $push: "$items"
          }
        }
      }
    ])
    
    1. 展开项目数组
    2. 按税组(使用 $arrayElemAt 的项目的第一个位置元素)
    3. 在项目阶段使用 objectToArray 上的映射来获取推入数组的键的值
    4. 使用 $group 推送数组以提供所需的输出

    输出:

    [
      {
        "_id": null,
        "items": [
          [
            "Tax",
            20,
            40,
            60
          ],
          [
            "FX Adjustments",
            20,
            40,
            60
          ]
        ]
      }
    ]
    

    【讨论】:

    • 如果数组元素超过3个怎么办?
    猜你喜欢
    • 2020-01-17
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多