我正在用Python构建MongoDB支持的API。我正在接收一系列文档以及其他一些ID。这是结构:
{
a_id: ObjectId("..."),
b_id: ObjectId("..."),
all_items: [
{item_id: ObjectId("..."), other_val: "I am other value"},
{item_id: ObjectId("..."), other_val: "I am another value"},
...
]
}
我要做的是:根据a_id, b_id & item_id
的值在一个集合中进行插入。因此,数据将按照以下方式在集合内部进行结构化:
{
a_id: ObjectId("..."),
b_id: ObjectId("..."),
item_id: ObjectId("..."),
other_val: "..."
}
因此,如果存在与a_id, b_id & item_id
匹配的文档,将对其进行更新,否则将其插入。
我是否需要为每个upsert遍历整个all_items
数组?请指教。
答案 0 :(得分:0)
您不必遍历数组;您可以将filter()与lambda expression结合使用,然后将其与其他条件结合起来:
编辑:代码示例已更新
import pymongo
from bson import ObjectId
db = pymongo.MongoClient()['mydatabase']
# Data setup
my_dict = {
'a_id': ObjectId("111111111111111111111111"),
'b_id': ObjectId("222222222222222222222222"),
'all_items': [
{'item_id': ObjectId("333333333333333333333333"), 'other_val': "I am other value"},
{'item_id': ObjectId("444444444444444444444444"), 'other_val': "I am another value"}
]
}
# Filter criteria setup
a_filter = ObjectId("111111111111111111111111")
b_filter = ObjectId("222222222222222222222222")
item_filter = ObjectId("444444444444444444444444")
db.mycollection.delete_many({})
for z in filter(lambda x: x.get('item_id') == item_filter, my_dict['all_items']):
db.mycollection.replace_one({'a_id': a_filter, 'b_id': b_filter, 'item_id': item_filter},
{'a_id': a_filter, 'b_id': b_filter, 'item_id': item_filter,
'other_val': z.get('other_val')},
upsert=True)
break # Remove this line if you want all matching items not just the first one found
给予:
> db.mycollection.findOne({}, {'_id': 0})
{
"a_id" : ObjectId("111111111111111111111111"),
"b_id" : ObjectId("222222222222222222222222"),
"item_id" : ObjectId("444444444444444444444444"),
"other_val" : "I am another value"
}