您需要使用聚合框架,在该框架中,您将运行一个聚合管道,该管道首先
venueList使用
$match
运算符根据ID 过滤集合中的文档。
第二个流水线将平整化
venueList和
sum子文档数组,以使文档中的数据作为非规范化条目进一步在流水线下方进行处理。该
$unwind
运营商在这里很有用。
$match
展开后,有必要使用进一步的过滤器,以便仅允许您要聚合的文档进入下一个管道。
主管道将是$group
运算符阶段,该运算符阶段使用累加器运算符聚合过滤后的文档以创建所需的总和$sum
。为了获得理想的结果,您将需要使用诸如$cond
创建独立计数字段的时间运算符,因为这将$sum
根据名称值将文档数量提供给表达式。
综上所述,请考虑运行以下管道:
db.collection.aggregate([ { "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } }, { "$unwind": "$venueList" }, { "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } }, { "$unwind": "$venueList.sum" }, { "$group": { "_id": null, "linux": { "$sum": { "$cond": [ { "$eq": [ "$venueList.sum.name", "linux" ] }, "$venueList.sum.value", 0 ] } }, "ubuntu": { "$sum": { "$cond": [ { "$eq": [ "$venueList.sum.name", "ubuntu" ] }, "$venueList.sum.value", 0 ] } } } }])要与mGo配合使用,您可以使用http://godoc.org/labix.org/v2/mgo#Collection.Pipe中的指南转换上述管道。
要获得比上述方法执行速度快得多并且还考虑了总和列表的未知值的更灵活,性能更好的替代方法,请按以下方式运行替代管道
db.collection.aggregate([ { "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } }, { "$unwind": "$venueList" }, { "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } }, { "$unwind": "$venueList.sum" }, { "$group": { "_id": "$venueList.sum.name", "count": { "$sum": "$venueList.sum.value" } } }, { "$group": { "_id": null, "counts": { "$push": { "name": "$_id", "count": "$count" } } } }])


