10

我有一些这样的数据:

data = [{'_id': 1, 'val': 5},
        {'_id': 2, 'val': 1}}]

数据库中的当前数据:

>>> db.collection.find_one()
    {'_id': 1, 'val': 3}

总是收到唯一的行,但不确定它们中的任何一个是否已经存在于 DB 中(例如上面的情况)。我想根据两种类型的要求更新它们。

要求 1

如果已经存在,请不要更新行。_id这在某种程度上很容易:

from pymongo.errors import BulkWriteError
try:
  db.collection.insert_many(data, unordered=False)
except BulkWriteError:
  pass

执行上述将插入2nd行但不会更新第一行;但它也引发了异常。

1.有没有更好的方法来做上述操作(用于批量插入)?

要求 2

这类似于update_if_exists&insert if not exists组合。所以以下数据:

data2 = [{'_id': 1, 'val': 9},
         {'_id': 3, 'val': 4}}]

应该更新该行_id=1并将该2nd行插入数据库中。

问题是我一次得到数千行,并且不确定逐一检查和更新是否有效。

2.这个要求在 MongoDB 中是否可能不需要迭代每一行并且尽可能少的操作?

4

1 回答 1

7

您可以生成一个更新列表以传递给批量写入 API,该 API 会将所有操作一起发送,但它们仍将在服务器上一一执行,但不会导致错误。

from pymongo import UpdateOne
data2 = [{'_id': 1, 'val': 9}, {'_id': 3, 'val': 4}]
upserts=[ UpdateOne({'_id':x['_id']}, {'$setOnInsert':x}, upsert=True) for x in data2]
result = db.test.bulk_write(upserts)

您可以在结果中看到,当找到 _id 时,该操作是空操作,但是当它没有找到时,它是一个插入操作。

于 2019-01-22T18:20:02.067 回答