在此answer 的指导下使用mapReduce 收集方法,您可以获得所需的结果。
这是一个使用以下选项的 pymongo 解决方案:
- map 函数 - 对要发出的键、值对(年月和金额)进行初始映射。
- reduce 函数 - 在这种情况下不需要任何操作。
- out - 指定将输出放在哪里 - 可以是一个集合,或者在这种情况下只是内联处理。
- 范围 - 指定滚动总计字段 - 仅称为总计
- finalize - 这是实际总计。
这是 python(pymongo) 代码:
from pymongo import MongoClient
from bson.code import Code
client = MongoClient()
db = client.tst1
coll = db.mapr1
map1 = Code('''
function () {
emit(
this.yearMonth,
this.amount
);
}
''')
reduce1 = Code('''
function (key, values) {
return value;
}
''')
fin1 = Code('''
function(key, value) {
total += value;
return {amount: value, balance: total};
}
''')
result = coll.map_reduce(map1, reduce1, out={'inline': 1}, scope={'total': 0}, finalize=fin1)
for doc in result['results']:
print(f'The doc is {doc}')
结果:
The doc is {'_id': 201908.0, 'value': {'amount': 100.0, 'balance': 100.0}}
The doc is {'_id': 201909.0, 'value': {'amount': 100.0, 'balance': 200.0}}
The doc is {'_id': 201910.0, 'value': {'amount': 200.0, 'balance': 400.0}}
The doc is {'_id': 201911.0, 'value': {'amount': 100.0, 'balance': 500.0}}
The doc is {'_id': 201912.0, 'value': {'amount': 200.0, 'balance': 700.0}}
The doc is {'_id': 202001.0, 'value': {'amount': 300.0, 'balance': 1000.0}}
The doc is {'_id': 202002.0, 'value': {'amount': 200.0, 'balance': 1200.0}}
集合中的文档:
{'_id': ObjectId('5e89c410b187b1e1abb089af'),
'amount': 100,
'yearMonth': 201908}
{'_id': ObjectId('5e89c410b187b1e1abb089b0'),
'amount': 100,
'yearMonth': 201909}
{'_id': ObjectId('5e89c410b187b1e1abb089b1'),
'amount': 200,
'yearMonth': 201910}
{'_id': ObjectId('5e89c410b187b1e1abb089b2'),
'amount': 100,
'yearMonth': 201911}
{'_id': ObjectId('5e89c410b187b1e1abb089b3'),
'amount': 200,
'yearMonth': 201912}
{'_id': ObjectId('5e89c410b187b1e1abb089b4'),
'amount': 300,
'yearMonth': 202001}
{'_id': ObjectId('5e89c410b187b1e1abb089b5'),
'amount': 200,
'yearMonth': 202002}