如何通过 ID 列表更新 mongodb 中的多个值?
How to update many values in mongodb by the list of IDs?
我使用 pymongo 与 mongodb 一起工作。问题是:我需要通过 ID 列表更新 mongodb 中的很多集合条目。
有一个集合 abcd
具有以下结构:
{'id': 'someid1', 'order': 0}
{'id': 'someid2', 'order': 0}
...
{'id': 'someidN', 'order': 0}
我需要用字典 mapping
中收集的值更改 order
字段。
mapping = {'someid1': 5, 'someid2': 7, ..., 'someidN': 50}
最明显的方法(可能不正确,因为它花了很多时间而且我中断了这个过程)是:
for key, value in mapping.items():
db.abcd.update_one({'id': key}, {'order': {'$set': value}})
但据我所知,这非常耗时。有什么聪明的方法可以通过值列表设置值吗?类似的东西(以下代码很愚蠢,无法按我的预期工作):
db.abcd.update_many({'id': list(mapping.keys())}, {'order': {'$set': list(mapping.values())})
我已阅读 mongodb 文档,但只找到带有“条件”的示例(例如,如果条件为真,则更改具有相同值的字段)。我想有一种有效的方法可以一次将值“映射”到多个 id。我是 mongodb(还有 pymongo)的新手,所以这个问题可能很愚蠢。谢谢。
Is there any smart way to set values by the list of values?
不幸的是,使用标准更新操作符。 Mongodb 的工作原理是需要一个更新过滤器,因此您尝试的任何事情都无法在单个 update_many()
.
中完成
确保在您的示例中 id
字段上 you have an index。 _id
字段始终被编入索引(并且始终是唯一的),您可以考虑改用它。
话虽如此,您的简单操作不应该太慢,除非您的机器/网络速度较慢或数据集非常大。 (注意虽然你的代码不应该工作 - 你的 $set
运算符在错误的地方)
加快速度的一个方法是使用 bulk write operations。下面的代码显示了如何做到这一点。
from pymongo import MongoClient, UpdateOne
import pprint
db = MongoClient()['mydatabase']
# Test Data setup
for i in range(3):
db.abcd.insert_one({'id': f'someid{i}', 'order': 0})
mapping = {'someid1': 5, 'someid2': 7}
updates = []
for key, value in mapping.items():
updates.append(UpdateOne({'id': key}, {'$set': {'order': value}}))
# print the results
db.abcd.bulk_write(updates)
pprint.pprint(list(db.abcd.find({}, {'_id': 0})))
returns:
[{'id': 'someid0', 'order': 0},
{'id': 'someid1', 'order': 5},
{'id': 'someid2', 'order': 7}]
我使用 pymongo 与 mongodb 一起工作。问题是:我需要通过 ID 列表更新 mongodb 中的很多集合条目。
有一个集合 abcd
具有以下结构:
{'id': 'someid1', 'order': 0}
{'id': 'someid2', 'order': 0}
...
{'id': 'someidN', 'order': 0}
我需要用字典 mapping
中收集的值更改 order
字段。
mapping = {'someid1': 5, 'someid2': 7, ..., 'someidN': 50}
最明显的方法(可能不正确,因为它花了很多时间而且我中断了这个过程)是:
for key, value in mapping.items():
db.abcd.update_one({'id': key}, {'order': {'$set': value}})
但据我所知,这非常耗时。有什么聪明的方法可以通过值列表设置值吗?类似的东西(以下代码很愚蠢,无法按我的预期工作):
db.abcd.update_many({'id': list(mapping.keys())}, {'order': {'$set': list(mapping.values())})
我已阅读 mongodb 文档,但只找到带有“条件”的示例(例如,如果条件为真,则更改具有相同值的字段)。我想有一种有效的方法可以一次将值“映射”到多个 id。我是 mongodb(还有 pymongo)的新手,所以这个问题可能很愚蠢。谢谢。
Is there any smart way to set values by the list of values?
不幸的是,使用标准更新操作符。 Mongodb 的工作原理是需要一个更新过滤器,因此您尝试的任何事情都无法在单个 update_many()
.
确保在您的示例中 id
字段上 you have an index。 _id
字段始终被编入索引(并且始终是唯一的),您可以考虑改用它。
话虽如此,您的简单操作不应该太慢,除非您的机器/网络速度较慢或数据集非常大。 (注意虽然你的代码不应该工作 - 你的 $set
运算符在错误的地方)
加快速度的一个方法是使用 bulk write operations。下面的代码显示了如何做到这一点。
from pymongo import MongoClient, UpdateOne
import pprint
db = MongoClient()['mydatabase']
# Test Data setup
for i in range(3):
db.abcd.insert_one({'id': f'someid{i}', 'order': 0})
mapping = {'someid1': 5, 'someid2': 7}
updates = []
for key, value in mapping.items():
updates.append(UpdateOne({'id': key}, {'$set': {'order': value}}))
# print the results
db.abcd.bulk_write(updates)
pprint.pprint(list(db.abcd.find({}, {'_id': 0})))
returns:
[{'id': 'someid0', 'order': 0},
{'id': 'someid1', 'order': 5},
{'id': 'someid2', 'order': 7}]