Mongodb 子文档中所有键的总值

Mongodb 子文档中所有键的总值,mongodb,aggregation-framework,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} } { '_id': 'Result', 'store_A_total

我有一个MongoDB集合,其中的文档如下所示:

{
    '_id': 'doc1',
    'store_A': {'apples': 50, 'oranges':20},
    'store_B': {'oranges': 15}
}
{
    '_id': 'doc2',
    'store_A': {'oranges':10},
    'store_B': {'apples': 15}
}
{
    '_id': 'Result',
    'store_A_total': {'apples': 50, 'oranges': 30},
    'store_B_total': {'apples': 15, 'oranges': 15}
}
如何编写聚合命令,在集合中的所有文档中为每个商店提供水果总数,而不枚举所有允许的水果种类?

结果应该如下所示:

{
    '_id': 'doc1',
    'store_A': {'apples': 50, 'oranges':20},
    'store_B': {'oranges': 15}
}
{
    '_id': 'doc2',
    'store_A': {'oranges':10},
    'store_B': {'apples': 15}
}
{
    '_id': 'Result',
    'store_A_total': {'apples': 50, 'oranges': 30},
    'store_B_total': {'apples': 15, 'oranges': 15}
}
此查询有效,但必须明确指定所有水果类型:

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'}
}})

是否有更好的方法来组织这些文档以方便此类查询?

mongodb聚合框架中没有一种方法可以处理 在文档内部键入可以检查或操作的数据。A. 解决方法是在此处转换您用作键的内容(例如,水果类型 并将名称)存储到如下值中:

{
    "_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
            }
            ]
        }
    ]
}
这使您能够在聚合中更轻松地处理这些数据:

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}}])
输出如下所示:

{
    "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
}

mongodb聚合框架中没有一种方法可以处理 在文档内部键入可以检查或操作的数据。A. 解决方法是在此处转换您用作键的内容(例如,水果类型 并将名称)存储到如下值中:

{
    "_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
            }
            ]
        }
    ]
}
这使您能够在聚合中更轻松地处理这些数据:

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}}])
输出如下所示:

{
    "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
}