SLe*_*Lee 4 performance mongodb pymongo pymongo-3.x
我正在更新一个拥有数百万个文档的数据库,其中包含少于10个_id冲突.
我目前正在使用PyMongo模块使用insert_many执行批量插入:
几百万个文档中只有大约10个冲突,我正在查询每个_id的数据库.我认为如果我可以删除查询过程,我可以减少一到两天的总插入时间.
是否存在类似于upsert的东西,如果它不存在则只插入文档?
处理此问题以及以有效方式"插入/更新"许多文档的更好方法是使用批量操作API以"批次"提交所有内容,同时有效地发送所有文档并在确认中接收"单一响应".
这可以通过两种方式处理.
首先忽略主键或其他索引上的任何"重复错误",然后您可以使用"UnOrdered"操作形式:
bulk = pymongo.bulk.BulkOperationBuilder(collection,ordered=False)
for doc in docs:
bulk.insert(doc)
response = bulk.execute()
Run Code Online (Sandbox Code Playgroud)
false那里的"UnOrdered"或参数意味着操作既可以按任何顺序执行,也可以完成"整个"批处理,只需在响应中"报告"任何实际错误.因此,这是基本上"忽略"重复项并继续前进的一种方法.
替代方法大致相同,但使用"upsert"功能以及$setOnInsert:
bulk = pymongo.bulk.BulkOperationBuilder(collection,ordered=True)
for doc in docs:
bulk.find({ "_id": doc["_id"] }).upsert().updateOne({
"$setOnInsert": doc
})
response = bulk.execute()
Run Code Online (Sandbox Code Playgroud)
由此,"查询"部分.find()用于使用"主键"或者可选地使用文档的"唯一键"来查询文档的存在.如果未找到匹配项,则会在创建新文档时发生"upsert".由于所有修改内容都在$setOnInsert其中,因此仅在发生"upsert"时才修改文档字段.否则,当文档"匹配"时,实际上没有关于此运算符下保存的数据的更改.
在这种情况下,"Ordered"意味着每个语句实际上都是以它创建的"相同"顺序提交的.此处的任何"错误"都将暂停更新(在发生错误的位置),这样就不会再有操作了做出承诺.它是可选的,但可能建议正常的"重复"行为,后面的语句"复制"前一个数据.
因此,对于更高效的写入,一般的想法是使用"批量"API并相应地构建您的操作.这里的选择实际上取决于来源的"插入顺序"对您是否重要.
当然,相同的"ordered"=False操作适用insert_many于在较新的驱动程序版本中实际使用"批量"操作的操作.但是,通过坚持使用简单的API"混合"操作的通用界面,您将获得更多的灵活性.
| 归档时间: |
|
| 查看次数: |
2325 次 |
| 最近记录: |