【问题标题】:MongoDb Aggregate nested documents with $addMongoDb 使用 $add 聚合嵌套文档
【发布时间】:2020-03-08 08:16:19
【问题描述】:

我需要从嵌套文档中获取总和值。

数据库文档:

{
  "_id": 123,
  "products": [
    {
      "productId": 1,
      "charges": [
        {
          "type": "che",
          "amount": 100
        }
      ]
    }
  ]
}

我想得到总和值。 sumValue = products.charges.amount+20; 其中"products.productId"1"products.charges.type""che"

我尝试了以下查询但没有希望:

db.getCollection('test').aggregate(
   [
        {"$match":{$and:[{"products.productId": 14117426}, {"products.charges.type":"che"}]},
     { $project: { "_id":0, total: { $add: [ "$products.charges.price", 20 ] } }}

   ]
)

请帮我解决这个问题。

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    你必须看看$unwind 操作符,它解构一个数组来为数组的每个元素输出一个文档。另请查看addproject 运算符。

    我假设你的数据库查询应该是这样的:

    db.test.aggregate([
    {$unwind: '$products'}, // Unwind products array
    {$match: {'products.productId' : 3}}, // Matching product id 
    {$unwind: '$products.charges'}, // Unwind charges
    {$match: {'products.charges.type' : 'che'}}, // Matching charge type of che 
    {$project: {'with20': {$add: ["$products.charges.amount",  20]}}}, // project total field which is value + 20
    {$group: {_id : null,      amount:  { $sum: '$with20' }}}  // total sum
    ])
    

    【讨论】:

    • 有没有办法使用相同的查询来更新 db 中的结果?喜欢使用 $Out 或 $merge 聚合器?
    • @phani,如果您使用 mongo 4.2,那么它是可能的,但我认为这对于更新数据库而不是生产使用更方便。看到这个:docs.mongodb.com/master/reference/command/update/…
    • 谢谢@thev0id。使用 $Merge 聚合器我认为我们不能更新同一个集合。并且使用 $set 我们无法保存聚合结果
    【解决方案2】:

    您可以运行两次$reduce 将您的数组转换为标量值。外部条件可以应用为$filter,内部条件可以应用为$cond

    db.collection.aggregate([
        {
            "$project": {
                _id: 0,
                total: {
                    $reduce: {
                        input: { $filter: { input: "$products", cond: [ "$$this.productId", 1 ] } },
                        initialValue: 20,
                        in: {
                            $add: [
                                "$$value",
                                {
                                    $reduce: {
                                        input: "$$this.charges",
                                        initialValue: 0,
                                        in: {
                                            $cond: [ { $eq: [ "$$this.type", "che" ] }, "$$this.amount", 0 ]
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        }
    ])
    

    Mongo Playground

    【讨论】:

    • 感谢您的回复。有没有办法使用单个查询更新文档中的“总”值?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 2020-12-31
    • 2021-03-13
    相关资源
    最近更新 更多