insert_many with upsert - PyMongo

时间:2016-05-25 11:21:24

标签: mongodb pymongo pymongo-3.x

我有一些这样的数据:

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

db中的当前数据:

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

始终 会收到唯一的行但不确定其中是否存在任何行(例如上面的情况)。我想根据两种要求更新它们。

要求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更新行,并在DB中插入2nd行。

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

2。 MongoDB中是否可以在不迭代每行并且操作尽可能少的情况下满足此要求?

1 个答案:

答案 0 :(得分:1)

您可以生成要传递给bulk write 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时该操作是无操作的,但是找不到时,它是一个插入操作。