2016-01-06 2 views
0

Я пытаюсь создать гистограмму MongoDB документов в следующем формате:Построение гистограммы из MongoDB с PyMongo

{ 
    "_id":1 
    "Properties":[ 
    { 
     "type": "a" 
    }, 
    { 
     "type": "d" 
    } 
    ] 
} 

{ 
    "_id":2 
    "Properties":[ 
    { 
     "type": "c" 
    }, 
    { 
     "type": "a" 
    } 
    ] 
} 

{ 
    "_id":3 
    "Properties":[ 
    { 
     "type": "c" 
    }, 
    { 
     "type": "d" 
    } 
    ] 
} 

Выход в данном примере должно быть:

а = 2

с = 2

д = 2

Мой обходной путь в данный момент входит эс запрашивая всю коллекцию:

collection.find({}) 

И после прохождения и накопления данных с помощью словаря питона. Я уверен, что в запросе MongoDB есть лучший способ сделать это, могу ли я получить эти данные в одном запросе, как я подозреваю?

Обратите внимание, что я не знаю, какие «типы» я могу найти до выполнения запроса.

ответ

3

В этом случае, вы можете использовать MongoDB aggregation.

Подробнее о Aggregation: https://docs.mongodb.org/manual/core/aggregation-introduction/

db.collection.aggregate([ 
    { $unwind : "$Properties" }, 
    { $group: { _id: "$Properties.type", count: { $sum: 1 } } } 
]); 

Выход:

{ 
    "result" : [ 
     { 
      "_id" : "c", 
      "count" : 2.0000000000000000 
     }, 
     { 
      "_id" : "d", 
      "count" : 2.0000000000000000 
     }, 
     { 
      "_id" : "a", 
      "count" : 2.0000000000000000 
     } 
    ], 
    "ok" : 1.0000000000000000 
} 

В Python:

from pymongo import MongoClient 

if __name__ == '__main__': 
    db = MongoClient().test 
    pipeline = [ 
     { "$unwind" : "$Properties" }, 
     { "$group": { "_id": "$Properties.type", "count": { "$sum": 1 } } } 
    ] 
    print list(db.collection.aggregate(pipeline)) 

Выход:

[{u'count': 2, u'_id': u'c'}, {u'count': 2, u'_id': u'd'}, {u'count': 2, u'_id': u'a'}] 
1

Не уверен, если это может соответствовать вашему сценарию, но вы можете сделать их отдельно от собственности, как:

count_a = collection.find({'Properties.type':'a'}).count() 
count_b = collection.find({'Properties.type':'b'}).count() 
count_c = collection.find({'Properties.type':'c'}).count() 

Если вы не знаете тип вы создаете переменную, которая будет принимать различные типы и может просто сделать что-то вроде:

mistery_type = 'assign the misery type in var when you know it' 
mistery_type_count = collection.find({'Properties.type': mistery_type}).count() 
+0

Я добавлю его к вопросу - я не знаю, какие типы я могу встретить до выполнения запроса. – GalB1t

+1

Это то, что вам нужно Я полагаю –

+0

Я также отредактировал свой ответ с другим примером, где вы можете поместить свой тип в переменную и быть более гибким с помощью count. –

 Смежные вопросы

  • Нет связанных вопросов^_^