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

时间:2016-03-18 11:30:30

标签: python mongodb mongodb-query pymongo

如果我需要在MongoDB中插入文档(如果它尚不存在)

db_stock.update_one(document, {'$set': document}, upsert=True)

。会做这份工作(如果我错了,请随时纠正我)

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

这个question有一个单一记录版本,但我需要它的大量版本,所以它有所不同。

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

2 个答案:

答案 0 :(得分:7)

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

db_stock.insert_many(<list of documents>)

ordered 选项文档中所述:

  

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}]

正如您可以看到带有_id 4的文档,5已插入到集合中。

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

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

答案 1 :(得分:0)

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

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