Mongodb:将分组后的子文档中的值求和,然后查找,然后展开

时间:2018-08-23 16:23:28

标签: arrays mongodb aggregation-framework

我有两个集合:具有相同结构的orders_A和orders_B(Web和应用程序订单):

orders_A:

{"_id": 100001,
"customer_id": 200001,
"order_value": 10,
"record_id": 11111,
"related_product": "No",
"Date_of_order": "12/07/2018"},

{"_id": 100002,
"customer_id": 200001,
"order_value": 15,
"record_id": 11112,
"related_product": "No",
"Date_of_order": "13/07/2018"}

orders_B:

{"_id": 102201,
"customer_id": 200001,
"order_value": 5,
"record_id": 22222,
"related_product": "No",
"Date_of_order": "09/07/2018"},

{"_id": 102202,
"customer_id": 200001,
"order_value": 5,
"record_id": 22223,
"related_product": "No",
"Date_of_order": "10/07/2018"}

我需要做的是回答“来自A和B的客户200001订单的总价值是多少?”

这是我到目前为止所拥有的:

db.orders_A.aggregate([
  {$match: {
    customer_id: 200001}},

  {$project: {
    customer_id:1,
    order_value:1}},

  {$group: {
    _id: "$customer_id",
    value_of_orders_a: {$sum: "$order_value"}}},

  {$lookup: {
    from: "orders_B",
    localField: "_id",
    foreignField: "customer_id",
    as: "orders_B"}},

  {$unwind {
    "path": "$record_id", "preserveNullAndEmptyArrays": true}}.pretty()

这是什么输出:

"_id": 200001,
"value_of_orders_a": 25,
"orders_b": {
    {"_id": 102201,
    "customer_id": 200001,
    "order_value": 5,
    "record_id": 22222,
    "related_product": "No",
    "Date_of_order": "09/07/2018"},

    {"_id": 102202,
    "customer_id": 200001,
    "order_value": 5,
    "record_id": 22223,
    "related_product": "No",
    "Date_of_order": "10/07/2018"}

我想创建一个“ value_of_orders_b”,然后最后一个“ total_orders_value”,它是这两个字段的总和

当我尝试再次分组并在展开后执行此操作时:

{ $group: {
  _id: "_id",
  value_of_orders_a: {$first: "$value_of_orders_a"},
  value_of_orders_b: {$sum: "$orders_b.order_value"}}}.pretty()

我得到输出:

"_id": 200001,
"value_of_orders_a": 25,
"value_of_orders_b": 0

为什么显示零?!我从原始代码中看到确实有与该用户关联的order_b订单!

所需的输出是:

"_id": 200001,
"value_of_orders_a": 25,
"value_of_orders_b": 10

我想得到的是此输出:

"_id": 200001,
"total_value_of_orders": 35

2 个答案:

答案 0 :(得分:1)

您可以尝试从monogodb 3.6 及更高版本

以下进行聚合
db.orders_A.aggregate([
  { "$limit": 1 },
  { "$facet": {
    "orders_B": [
      { "$match": { "customer_id": 200001 }},
      { "$lookup": {
        "from": "orders_B",
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$customer_id", 200001 ] } } },
        ],
        "as": "orders_B"
      }}
    ],
    "orders_A": [
      { "$match": { "customer_id": 200001 }},
      { "$lookup": {
        "from": "orders_A",
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$customer_id", 200001 ] } } },
        ],
        "as": "orders_A"
      }}
    ]
  }},
  { "$project": {
    "data": { "$concatArrays": [ "$orders_A", "$orders_B" ] }
  }},
  { "$unwind": "$data" },
  { "$replaceRoot": { "newRoot": "$data" } },
  { "$group": {
    "_id": "$customer_id",
    "total_value_of_orders": { "$sum": "$order_value" }
  }}
])

答案 1 :(得分:1)

您可以将$unwind之后的$group$lookup替换为$project以下的阶段。

保留所有阶段,直到$lookup,然后在末尾添加$project

{$project:{total_value_of_orders:{$add:["$value_of_orders_a",{$sum:"$orders_b.order_value"}]}}}