使用pymongo聚合整个mongodb对象

时间:2017-04-02 14:35:17

标签: python 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个字段)。

1 个答案:

答案 0 :(得分: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}