Sup*_*e99 1 mongodb aggregation-framework
我有一个MongoDB集合,其文档看起来像:
{
'_id': 'doc1',
'store_A': {'apples': 50, 'oranges':20},
'store_B': {'oranges': 15}
}
{
'_id': 'doc2',
'store_A': {'oranges':10},
'store_B': {'apples': 15}
}
Run Code Online (Sandbox Code Playgroud)
我如何编写一个聚合命令来为我提供集合中所有文档中每个商店的水果总数而不包括所有允许的水果种类?
结果应如下所示:
{
'_id': 'Result',
'store_A_total': {'apples': 50, 'oranges': 30},
'store_B_total': {'apples': 15, 'oranges': 15}
}
Run Code Online (Sandbox Code Playgroud)
此查询有效,但必须明确指定所有水果类型:
db.collection.aggregate(
{'$group': {'_id': 'Result',
'store_A_apples': {'$sum': '$Store_A.apples'},
'store_A_oranges': {'$sum': '$store_A.oranges'},
'store_B_apples': {'$sum': '$store_B.apples'},
'store_B_oranges': {'$sum': '$store_B.oranges'}
}},
{'$project': {
'store_A': {'apples': '$store_A_apples','oranges': '$store_A_oranges'},
'store_B': {'apples': '$store_B_apples','oranges': '$store_B_oranges'}
}})
Run Code Online (Sandbox Code Playgroud)
是否有更好的方法来构建这些文档以促进此类查询?
在mongodb聚合框架中没有办法将文档内部的键视为可以检查或操作的数据.解决方法是将您在此处使用的键(例如水果类型和商店名称)转换为如下值:
{
"_id" : "doc1",
"stores":[
{
// store name is a value
"name":"store_A",
"inventory": [
{
// so is fruit type
"type" : "apple",
"count" : 50
},
{
"type" : "orange",
"count" : 20
}
]
},
{
"name": "store_B",
"inventory": [
{
"type" : "orange",
"count" : 15
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
这使您可以更轻松地在聚合中处理这些数据:
db.coll.aggregate([
// split documents by store name
{$unwind:"$stores"},
// split documents further by fruit type
{$unwind:"$stores.inventory"},
// group documents together by store/fruit type, count quantities of fruit
{$group:{"_id":{"store":"$stores.name", "fruit":"$stores.inventory.type"},
"count":{$sum:"$stores.inventory.count"}}},
// reformat the data to look more like your specification
{$project:{
"store":"$_id.store",
"fruit":"$_id.fruit",
"_id":0,
"count":1}}])
Run Code Online (Sandbox Code Playgroud)
输出如下:
{
"result" : [
{
"count" : 15,
"store" : "store_B",
"fruit" : "apple"
},
{
"count" : 15,
"store" : "store_B",
"fruit" : "orange"
},
{
"count" : 30,
"store" : "store_A",
"fruit" : "orange"
},
{
"count" : 50,
"store" : "store_A",
"fruit" : "apple"
}
],
"ok" : 1
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
592 次 |
| 最近记录: |