对数组中的值求和

时间:2016-04-20 20:31:18

标签: mongodb mongodb-query

  coll1[   **coll1 is the collection name**
    {"_id" : ObjectId("571489d66e58990374e0d2d3"), 
         "cbill_details":[ **cbill_details is a json array.**
           {"total-sell":22, "price":1212}, **total-sell represent no of item sold in a perticular bill**
           {"total-sell":24, "price":1512}
          ], **here the total-sell is (22+24)=46.that is whay i want to select this document**
        "product_name":"jeans"
        }, **end of document 1** 
        {"_id" : ObjectId("571489d66e58990374e0d2d4"), 
         "cbill_details":[
           {"total-sell":10, "price":182},
           {"total-sell":15, "price":223}
          ],**here the total-sell is (10+15)=25,which is less than 30 that is whay i donot want to select this document**
        "product_name":"t-shirt"
        } **end of document 2** 
    ]

我想在那里获取文件,total-sell的总数大于30。

2 个答案:

答案 0 :(得分:2)

不需要任何小组,只需要一个项目和匹配。

db.coll1.aggregate([{
    $project : {
        total: {$sum: "$cbill_details.total-sell"}
    }
}, {
    $match: {
        total: { $gt: 30 }
    }
}])

产地:

{
    "_id" : ObjectId("571489d66e58990374e0d2d3"),
    "total" : 46
}

答案 1 :(得分:0)

使用MongoDB 3.2,您可以使用$redact表达式,因为$sum实际上可以直接在该版本中的数组上工作:

db.collection.aggregate([
    { "$redact": {
        "if": { "$gt": [ { "$sum": "cbill_details.total-sell"  }, 30 ] },
        "then": "$$KEEP",
        "else": "$$PRUNE"
    }}
])

在早期版本中,聚合表达式不值得花费,因为在$unwind数组元素中需要$sum。因此,您可以使用$where

替代执行此操作
db.collection.find(function() {
    return Array.sum(this.cbill_details.map(function(el) {
        return el["total-sell"]
    })) > 30;
})

但是当然两者都需要“扫描”整个集合以确定要返回的文档。这样效率不高

这里要学到的真正教训应该是将总数作为财产保留在文档中。实际上,您可以使用$inc运算符添加每个数组条目来增加此总计:

db.collection.update(
    { "_id": id },
    {
       "$push": { "cbill_details": { "total-sell": 22, "price": 1512 } },
       "$inc": {
           "order-total-sell": 22
       }
    }
)

通过这种方式,数组中所有项目的总数已经在文档中,这是一个可以直接查询甚至索引的属性。那么就直接查询:

db.collecion.find({ "order-total-sell": { "$gt": 30 } })

这将是执行此操作的最高效方式,因此通常建议始终在文档中保留“总计”属性,并在应用每个更新时保持总计。