Subtract $sum from Sub-document

前端 未结 1 1434
眼角桃花
眼角桃花 2021-01-26 12:07

Given the following record in my MongoDB table:

{
    \"_id\" : ObjectId(\"5a00c1c71680084c55811ae2\"),
    \"name\" : \"test\",
    \"tenantId\" : \"paul\",
           


        
相关标签:
1条回答
  • 2021-01-26 13:01

    Actually you can simply do:

    db.table.aggregate( [
      { "$match" : { "tenantId": "paul" } },
      //{ $unwind:{ path: "$deposits", preserveNullAndEmptyArrays: true  }},
      { "$project":
        "deposits": { "$subtract": ["$price", { "$sum": "$deposits.amount" } ] }
      }}
    ])
    

    Since MongoDB 3.2 you can actually $project with $sum and an array of arguments ( or an array ) and therefore do not need to $unwind at all.

    Changed in version 3.2: $sum is available in the $group and $project stages. In previous versions of MongoDB, $sum is available in the $group stage only.

    When used in the $project stage, $sum returns the sum of the specified expression or list of expressions for each document ...

    The "long" way, which is the "old" way is to actually use $unwind, but you would then actually add a $project following the $group:

    db.table.aggregate( [
      { "$match" : { "tenantId": "paul" } },
      { $unwind:{ path: "$deposits", preserveNullAndEmptyArrays: true  }},
      { "$group":
        "_id": "$_id",
        "price": { "$first": "$price" },
        "deposits": { "$sum": "$deposits.amount" }
      }},
      { "$project": {
        "deposits": { "$subtract": [ "$price", "$deposits" ] }
      }}
    ])
    

    And of course you then need the $first accumulator in order to return the "price" field from the $group stage so it can be used in the following stage.

    But if you can do preserveNullAndEmptyArrays, then you actually have MongoDB 3.2, and therefore are better off using the statement without the $unwind at all, since it's much faster to do it that way.

    0 讨论(0)
提交回复
热议问题