更好的方式来处理这个问题,也有“插入/更新”许多文件以有效的方式是使用Bulk Operations API提交的所有信息在“批”与所有的effecient发送和接收的“奇回应”确认。
这可以通过两种方式处理。
首先忽略主键或其他指标的任何“重复错误”,那么你可以使用“无序”的形式操作:
bulk = pymongo.bulk.BulkOperationBuilder(collection,ordered=False)
for doc in docs:
bulk.insert(doc)
response = bulk.execute()
的“无序”或false
说法存在,使得运营都可以以任何顺序执行,并且“完整”批处理将完成,只是在响应中“报告”任何实际错误。所以这是一种基本上“忽略”重复和移动的方法。
的另一种方法是大致相同,但使用与$setOnInsert
沿着“更新插入”功能性:
bulk = pymongo.bulk.BulkOperationBuilder(collection,ordered=True)
for doc in docs:
bulk.find({ "_id": doc["_id"] }).upsert().updateOne({
"$setOnInsert": doc
})
response = bulk.execute()
由此.find()
“查询”部分用于查询为一个文件,使用存在的“主键“或备选地文档的”唯一键“。如果找不到匹配,则在创建新文档时会出现“upsert”。由于所有修改内容都在$setOnInsert
之内,因此只有在发生“upsert”时才会修改文档字段。否则,在文件“匹配”的情况下,对于保存在该操作员下的数据,实际上没有任何变化。
在这种情况下,“有序”意味着每个语句实际上是以它创建的“相同”顺序提交的。此外,任何“错误”都会停止更新(在发生错误的位置),以便没有更多的操作会被执行。它是可选的,但可能建议用于正常的“重复”行为,其中后面的语句“复制”前一个数据。
因此,为了更有效的写入,总体思路是使用“Bulk”API并相应地构建您的操作。这里的选择实际上取决于来源的“插入顺序”是否对您很重要。
当然,"ordered"=False
操作适用于insert_many
,它实际上在较新的驱动程序版本中使用“批量”操作。但通过使用简单的API可以“混合”操作的通用界面,您将获得更大的灵活性。
Gotcha。因此,使用带有“ordered”= False的insert_many将继续运行所有插入,而忽略可能弹出的任何错误? – SLee
@SLee它应该。有些API已被“修改”,所以结果实际上会引发异常(以前不是这种情况),但“整个”批处理应该执行。另一方面,“upsert”选项不能抛出异常(来自重复键),因为它并不意味着它的任何操作错误。正如我所说,*“关键在于操作顺序是否重要”*。 –