如何使用PyMongo在重复键错误后继续插入

ORA*_*600 8 python mongodb pymongo mongodb-query

如果我还需要在MongoDB中插入文档

db_stock.update_one(document, {'$set': document}, upsert=True)
Run Code Online (Sandbox Code Playgroud)

.会做的工作(如果我错了,请随时纠正我)

但是,如果我有一份文件清单并希望将它们全部插入,那么最好的方法是什么呢?

这个问题有一个单一记录版本,但我需要它的大量版本,所以它是不同的.

让我重新提出我的问题.我有数百万个文档,其中很少可以存储.如何在几秒钟内将其余的存储在MongoDB中,而不是几分钟/小时?

sty*_*ane 8

您需要使用insert_many方法并将有序选项设置为False.

db_stock.insert_many(<list of documents>)
Run Code Online (Sandbox Code Playgroud)

订购选项文档中所述:

ordered(可选):如果True(默认)文档将按顺序插入服务器,按提供的顺序.如果发生错误,则中止所有剩余插入.如果为False,文档将以任意顺序插入服务器,可能并行,并且将尝试所有文档插入.

这意味着即使存在重复键错误,插入仍将继续.

演示:

>>> c.insert_many([{'_id': 2}, {'_id': 3}])
<pymongo.results.InsertManyResult object at 0x7f5ca669ef30>
>>> list(c.find())
[{'_id': 2}, {'_id': 3}]
>>> try:
...     c.insert_many([{'_id': 2}, {'_id': 3}, {'_id': 4}, {'_id': 5}], ordered=False)
... except pymongo.errors.BulkWriteError:
...     list(c.find())
... 
[{'_id': 2}, {'_id': 3}, {'_id': 4}, {'_id': 5}]
Run Code Online (Sandbox Code Playgroud)

正如您所见,带有_id4的文档,5被插入到集合中.


值得注意的是,在使用该insertMany方法的shell中也可以这样做.您只需将未记录的选项设置orderedfalse.

db.collection.insertMany(
    [ 
        { '_id': 2 }, 
        { '_id': 3 },
        { '_id': 4 }, 
        { '_id': 5 }
    ],
    { 'ordered': false }
)
Run Code Online (Sandbox Code Playgroud)


Tho*_*oll 0

bulkWrite可以做到这一点,虽然我不确定 pymongo 命令是什么,但这是直接的 mongodb 查询:

db.products.insert([
  { _id: 11, item: "pencil", qty: 50, type: "no.2" },
  { item: "pen", qty: 20 },
  { item: "eraser", qty: 25 }
])
Run Code Online (Sandbox Code Playgroud)