使用update_one更新pymongo中的嵌套字典(Python MongoDB)

2022-03-14 00:00:00 python mongodb pymongo database

问题描述

假设我有以下函数:

def insert_data(self, data, id):
    self.snapshots.update_one({'snapshot_id': id},
                              {'$set': {'topic': data}}, upsert=True) 

数据始终是具有单个条目(一个键-值对)的字典。 每次调用此函数时,"data"持有不同的密钥。 我希望每个调用都将该键-值对添加到"Theme"下。

假设数据在第一次调用时为{1:2},在第二次调用时为{3:4}。 我想在两次通话后有{‘Theme’:{1:2,3:4}}。 我怎样才能做到这一点呢?上面的函数覆盖了数据字典,因此只保留最后一个(在这种情况下,我以{‘Theme’:{3:4}}结束)。

它一定没有那么复杂,但我无法使其正常工作。


解决方案

从MongoDB4.2版本开始,您可以使用Updates with Aggregation Pipeline新功能来获得您想要的结果。

只需用括号[]将更新括起来,就可以让mongo使用聚合并实际更新文档。

尝试这样的操作:

print(f'Document before update')
pprint.pprint(coll.find_one())


def insert_data(data, id):
    for key, value in data.items():
        coll.update_one({'snapshot_id': id}, 
                        [{'$set': {'topic': {str(key): value}}}])


data_dict = {1: 6, 3: 8, 5: 6}

for k, v in data_dict.items():
    insert_data({k: v}, 'Demo1')

    print(f'
Document after update')
    pprint.pprint(coll.find_one())

结果:

Document before update
{'_id': ObjectId('5e799063caf64cd83bfda524'), 'snapshot_id': 'Demo1'}

Document after update
{'_id': ObjectId('5e799063caf64cd83bfda524'),
 'snapshot_id': 'Demo1',
 'topic': {'1': 6}}

Document after update
{'_id': ObjectId('5e799063caf64cd83bfda524'),
 'snapshot_id': 'Demo1',
 'topic': {'1': 6, '3': 8}}

Document after update
{'_id': ObjectId('5e799063caf64cd83bfda524'),
 'snapshot_id': 'Demo1',
 'topic': {'1': 6, '3': 8, '5': 6}}

相关文章