【问题标题】:MongoDb aggregation with arrays inside an array possibleMongoDb 聚合与数组内的数组可能
【发布时间】:2020-06-08 12:57:34
【问题描述】:

我正在努力寻找一些使用 mongo 聚合框架来处理具有项目数组的文档的示例,其中每个项目还具有其他对象的数组(包含数组的数组)

在下面的示例文档中,我真正想要的是一个示例,它对文档中所有案例的结果数组中的 itemValue 求和,并跨越集合,其中 result.decision 被“接受”并按文档 locationCode

但是,即使是找到所有文档的示例,其中 result.decision 被“接受”以显示或汇总 itemValue 的相同内容也会有所帮助

非常感谢

{
"_id": "333212",
"data": {
    "locationCode": "UK-555-5566",
    "mode": "retail",
    "caseHandler": "A N Other",
    "cases": [{
            "caseId": "CSE525666",
            "items": [{
                    "id": "333212-CSE525666-1",
                    "type": "hardware",
                    "subType": "print cartridge",
                    "targetDate": "2020-06-15",
                    "itemDetail": {
                        "description": "acme print cartridge",
                        "quantity": 2,
                        "weight": "1.5"
                    },
                    "result": {
                        "decision": "rejected",
                        "decisionDate": "2019-02-02"
                    },
                    "isPriority": true
                },
                {
                    "id": "333212-CSE525666-2",
                    "type": "Stationery",
                    "subType": "other",
                    "targetDate": "2020-06-15",
                    "itemDetail": {
                        "description": "staples box",
                        "quantity": 3,
                        "weight": "1.66"
                    },
                    "result": {
                        "decision": "accepted",
                        "decisionDate": "2020-03-03",
                        "itemValue": "23.01"
                    },
                    "isPriority": true
                }
            ]
        },
        {
            "caseId": "CSE885655",
            "items": [{
                    "id": "333212-CSE885655-1",
                    "type": "marine goods",
                    "subType": "fish food",
                    "targetDate": "2020-06-04",
                    "itemDetail": {
                        "description": "fish bait",
                        "quantity": 5,
                        "weight": "0.65"
                    },
                    "result": {
                        "decision": "accepted",
                        "decisionDate": "2020-03-02"
                    },
                    "isPriority": false
                },
                {
                    "id": "333212-CSE885655-4",
                    "type": "tobacco products",
                    "subType": "cigarettes",
                    "deadlineDate": "2020-06-15",
                    "itemDetail": {
                        "description": "rolling tobbaco",
                        "quantity": 42,
                        "weight": "2.25"
                    },
                    "result": {
                        "decision": "accepted",
                        "decisionDate": "2020-02-02",
                        "itemValue": "48.15"
                    },
                    "isPriority": true
                }
            ]
        }
    ]
},
"state": "open"

}

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    您可能正在寻找$unwind。它在文档中获取一个数组,并为每个数组成员创建一个单独的文档。

    { foos: [1, 2] } -> { foos: 1 }, { foos: 2}
    

    这样您就可以创建一个平面文档结构并像往常一样进行匹配和分组。

    db.collection.aggregate([
      {
        $unwind: "$data.cases"
      },
      {
        $unwind: "$data.cases.items"
      },
      {
        $match: {
          "data.cases.items.result.decision": "accepted"
        }
      },
      {
        $group: {
          _id: "$data.locationCode",
          value: {
            $sum: {
              $toDecimal: "$data.cases.items.result.itemValue"
            }
          }
        }
      },
      {
        $project: {
          _id: 0,
          locationCode: "$_id",
          value: "$value"
        }
      }
    ])
    

    https://mongoplayground.net/p/Xr2WfFyPZS3

    【讨论】:

    • 非常感谢这是一个很有帮助的答案。我想我也可以将此示例用作我需要的其他查询的起点。 $unwind 似乎是一个非常好的解决方案,并且聚合示例比我希望的要简洁得多。非常感谢。
    【解决方案2】:

    替代解决方案...

    我们按data.locationCode 分组并将所有符合此条件的项目相加:
    cases[*].items[*].result.decision" == "accepted"


    db.collection.aggregate([
      {
        $group: {
          _id: "$data.locationCode",
          itemValue: {
            $sum: {
              $reduce: {
                input: "$data.cases",
                initialValue: 0,
                in: {
                  $sum: {
                    $concatArrays: [
                      [ "$$value" ],
                      {
                        $map: {
                          input: {
                            $filter: {
                              input: "$$this.items",
                              as: "f",
                              cond: {
                                $eq: [ "$$f.result.decision", "accepted" ]
                              }
                            }
                          },
                          as: "item",
                          in: {
                            $toDouble: {
                              $ifNull: [ "$$item.result.itemValue", 0 ]
                            }
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    ])
    

    MongoPlayground

    【讨论】:

    • 感谢您的选择。这对帮助我看到不同的方法非常有帮助,我也可以使用这些想法和方法来构建进一步的查询。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多