我有一个看起来像这样的收藏集:
{
{"name": "aaa", "value": 100},
{"name": "bbb", "value": 50},
{"name": "ccc", "value": 200},
}
并想象我有一个这样的字典:
{
{"name": "aaa", "value": 40},
{"name": "ccc", "value": -100},
{"name": "ddd", "value": 200},
}
我想将字典合并到集合中,方法是添加名称未出现在集合中的文档,并在名称相等的文档之间合并2值。集合应该像这样结束:
{
{"name": "aaa", "value": 140},
{"name": "bbb", "value": 50},
{"name": "ccc", "value": 100},
{"name": "ddd", "value": 200},
}
我已经检查了replace_many,insert_many和update_many,但看起来无法使其表现得像我想要的那样。
目前,我正在对所有不存在的文档进行基本的insert_many,并为每个存在的文档进行replace_one,但我想做一些更优化的事情。
先谢谢您
您需要通过update_one()
运算符将upsert=True
与$inc
一起使用:
from pymongo import MongoClient
from bson.json_util import dumps
db = MongoClient()['mydatabase']
item1 = [
{"name": "aaa", "value": 100},
{"name": "bbb", "value": 50},
{"name": "ccc", "value": 200}
]
item2 = [
{"name": "aaa", "value": 40},
{"name": "ccc", "value": -100},
{"name": "ddd", "value": 200}
]
for item in [item1, item2]:
for record in item:
db.mycollection.update_one({'name': record.get('name')}, {'$inc': {'value': record.get('value')}}, upsert=True)
print(dumps(db.mycollection.find({}, {'_id': 0}), indent=4))
给予:
[
{
"name": "aaa",
"value": 140
},
{
"name": "bbb",
"value": 50
},
{
"name": "ccc",
"value": 100
},
{
"name": "ddd",
"value": 200
}
]
您可以尝试以下代码:
import pymongo
from pymongo import UpdateOne
import json
import sys
inputArray = [
{"name": "aaa", "value": 40},
{"name": "ccc", "value": -100},
{"name": "ddd", "value": 200},
]
bulkArr = []
for x in inputArray:
bulkArr.append(
UpdateOne({"name": x['name']}, {'$inc': {'value': x['value']}}, upsert=True))
# print('[%s]' % ', '.join(map(str, bulkArr)))
try:
result = db.collection.bulk_write(bulkArr)
# Opt for below - if you want to proceed on all dictionaries to be updated, even though an error occured in between for one dict
# result = db.collection.bulk_write(bulkArr, ordered=False)
print(result.bulk_api_result)
except:
e = sys.exc_info()[0]
print("An exception occurred ::", e) ## Get the ids failed if any & do re-try