我有一个用例,我将文档存储在mongo集合中,其中一列作为map。例如:
{ "_id" : ObjectId("axa"), "date" : "2015-08-05", "key1" : "abc", "aggregates" : { "x" : 12, "y" : 1 } }
{ "_id" : ObjectId("axa1"), "date" : "2015-08-04", "key1" : "abc", "aggregates" : { "x" : 4, "y" : 19 } }
{ "_id" : ObjectId("axa2"), "date" : "2015-08-03", "key1" : "abc", "aggregates" : { "x" : 3, "y" : 13 } }
需要注意的一点是聚合子文档中的键可能会发生变化。例如,代替x和y,它可以是z和k或任何组合和任何数字
现在我从API中提取数据,需要使用mongo聚合框架来聚合日期范围。例如,对于上面的示例,我想运行日期08/03 -08/05的查询并聚合x和y(按x和y分组),结果应为
{ "key1" : "abc", "aggregates" : { "x" : 19, "y" : 33 } }
我该怎么做?
答案 0 :(得分:0)
首先,您应该更新文档,因为date
是字符串。您可以使用Bulk()
API
from datetime import datetime
import pymongo
conn = pymongo.MongoClient()
db = conn.test
col = db.collection
bulk = col.initialize_ordered_bulk_op()
count = 0
for doc in col.find():
conv_date = datetime.strptime(doc['date'], '%Y-%m-%d')
bulk.find({'_id': doc['_id']}).update_one({'$set': {'date': conv_date}})
count = count + 1
if count % 500 == 0:
# Execute per 500 operations and re-init.
bulk.execute()
bulk = col.initialize_ordered_bulk_op()
# Clean up queues
if count % 500 != 0:
bulk.execute()
然后是聚合部分:
您需要使用$match
运算符按date
过滤文档。按指定的标识key1
下一步$group
您的文档并应用累加器$sum
。使用$project
,您可以重塑文档。
x = 'x'
y = 'y'
col.aggregate([
{'$match': { 'date': { '$lte': datetime(2015, 8, 5), '$gte': datetime(2015, 8, 3)}}},
{'$group': {'_id': '$key1', 'x': {'$sum': '$aggregates. ' +x}, 'y': {'$sum': '$aggregates.' + y}}},
{'$project': {'key1': '$_id', 'aggregates': {'x': '$x', 'y': '$y'}, '_id': 0}}
])