2017-04-02 38 views
0

我有一个包含一些大型对象的数据库,总是具有相同的键/结构的整个MongoDB的对象:碎石pymongo

{ 
    "stats": { 
    "a": 100 
    "b": 0 
    "c": 30 
    "d": 20 
    ... 
    "z": 100 
    } 
}, 
{ 
    "stats": { 
    "a": 200 
    "b": 2 
    "c": 10 
    "d": 40 
    ... 
    "z": 100 
    } 
} 

我想知道是否有聚合所有stats子的方式而不用PyMongo指定所有的字段。所需的输出会是这样:

"stats": { 
    "a": 150 
    "b": 1 
    "c": 20 
    "d": 30 
    ... 
    "z": 100 
} 

我发现这一点:Mongodb Is it possible to aggregate an object?但我有点不确定如何在PyMongo使用它。

编辑:我可以列出所有领域和聚合他们,但我正在寻找一个解决方案,不列出这些领域(我有大约100他们)。

+0

我想确认您想每个键搞定值的平均值,是吗? – gzc

+0

是的,这正是我正在寻找 – FunkySayu

回答

1

有没有内置的做你所问的,至少不是我所知道的。

你可以做的一件事是在Python中动态构建管道。由于每个文档具有相同的字段,因此您可以执行find_one并使用它来获取字段集并从中构建聚合管道。

例如:

import pprint 
from pymongo import MongoClient 
client = MongoClient() 

pp = pprint.PrettyPrinter(indent=4) 
db = MongoClient().test 
collection = db.foo 

pipeline = [{ 
    '$group': { 
     '_id' : None 
    } 
}] 

group = pipeline[0]['$group'] 

doc = collection.find_one() 

for k in doc['stats']: 
    group[k] = {'$avg' : '$stats.'+k} 


pp.pprint(pipeline) 

cursor = collection.aggregate(pipeline, allowDiskUse=True) 

for doc in cursor: 
    pp.pprint(doc) 

输出:

[ { '$group': { '_id': None, 
         u'a': { '$avg': u'$stats.a'}, 
         u'b': { '$avg': u'$stats.b'}, 
         u'c': { '$avg': u'$stats.c'}, 
         u'd': { '$avg': u'$stats.d'}, 
         u'z': { '$avg': u'$stats.z'}}}] 
{ u'_id': None, u'a': 150.0, u'b': 1.0, u'c': 20.0, u'd': 30.0, u'z': 100.0} 
+0

是否有没有使用map-reduce功能的方法?我无法想象如何编写它,但这个解决方案是一个非常好的开始。 – FunkySayu

+0

您可以使用map reduce来做到这一点,但是聚合框架会更好地执行。地图缩小应该是最后的手段。 – helmy