首页 > 解决方案 > MongoDB聚合:如何添加一个嵌套字段,它是一个双重嵌套字段的总和?

问题描述

我有以下结构的多个文档。

{
  "_id": ObjectId("60c07a1f9853c900c2026440"),
  "ProductID": "A",
  "Colours": [
    {
      "ID": "01",
      "Name": "BLACK",
      "Sizes": [
        {
          "Code": "S1",
          "Stock": 2
        },
        {
          "Code": "S2",
          "Stock": 3
        }
      ] 
    },
    {
      "ID": "02",
      "Name": "WHITE",
      "Sizes": [
        {
          "Code": "S1",
          "Stock": 5
        },
        {
          "Code": "S2",
          "Stock": 2
        }
      ] 
    }  
  ]
}  

我想在每个Colours被调用的元素内使用一个附加字段检索文档,该字段TotalStock包含Stock来自所有Sizes内部的总和,同时忽略Sizes它们本身。

所以我检索到的文档看起来像这样:

{
  "ProductID": "A",
  "Colours": [
    {
      "ID": "01",
      "Name": "BLACK",
      "TotalStock":5
    },
    {
      "ID": "02",
      "Name": "WHITE",
      "TotalStock":7
    }  
  ]
}  

我能够通过 , 和 的组合在一定程度上$unwind实现$addFields$sum一点$project。这是我的查询:

db.collection.aggregate([
  {
    "$unwind": "$Colours"
  },
  {
    "$addFields": {
      "Colours.TotalStock": {
        "$sum": "$Colours.Sizes.Stock"
      }
    }
  },
  {
    "$project": {
      "_id": 0,
      "ProductID": 1,
      "Colours.ID": 1,
      "Colours.Name": 1,
      "Colours.TotalStock": 1,
    }
  }
])

问题

我的查询为每种颜色提供了一个单独的文档,因为$unwind我需要它们在同一个文档中。我仍在学习,不知道如何以及是否应该使用$group它。我需要在查询中进行哪些更改才能获得预期的结果?

是一个带有上述示例和查询的游乐场。

标签: mongodbmongodb-queryaggregation-framework

解决方案


$unwind $group等在集合级别上工作,并且如果您需要的所有信息都在 1 个文档中,也会破坏您不需要它们的文档结构。(但有时它们更易于使用)。

相反,您可以在不更改文档结构的情况下在文档级别使用、和执行操作$map$filter$reduce

db.collection.aggregate([
  {
    "$addFields": {
      "Colours": {
        "$map": {
          "input": "$Colours",
          "as": "color",
          "in": {
            "$mergeObjects": [
              "$$color",
              {
                "TotalStock": {
                  "$reduce": {
                    "input": "$$color.Sizes",
                    "initialValue": 0,
                    "in": {
                      "$let": {
                        "vars": {
                          "total_stock": "$$value",
                          "csize": "$$this"
                        },
                        "in": {
                          "$add": [
                            "$$total_stock",
                            "$$csize.Stock"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

测试代码在这里

查询不会更改文档,只会添加一个名为的额外字段$TotalStock


推荐阅读