MongoDB Bulk Write Operations

2024-06-14 20:26:09 浏览数 (2)

Hi~朋友,关注置顶防止错过消息

MongoDB提供了批量写入的能力,包含批量插入、更新和删除,函数如下:

  1. db.collection.bulkWrite(
  2. [ <operation 1>, <operation 2>, ... ],
  3. {
  4. writeConcern : <document>,
  5. ordered : <boolean>
  6. }
  7. )
  • operation是一个批量更新操作的数组,取值有insertOne,deleteOne,updateOne,deleteMany,updateMany,replaceOne
  • writeConcern:写关注的级别
  • ordered:是否顺序执行,如果为true顺序执行遇到错误停止执行后续操作,如果为false,执行过程遇到错误忽略并继续执行后续的任务,默认值false

insertOne操作

  1. db.collection.bulkWrite( [
  2. { insertOne : { "document": <document>} }
  3. ] )

updateOne操作

  1. db.collection.bulkWrite( [
  2. { updateOne :
  3. {
  4. "filter": <document>,
  5. "update": <document or pipeline>,
  6. "upsert": <boolean>,
  7. "collation": <document>,
  8. "arrayFilters": [ <filterdocument1>, ... ],
  9. "hint": <document|string>
  10. }
  11. }
  12. ] )
  • filter:用来过滤需要更新的数据
  • update:更新操作,这里可以是只包含update operator的document 或者聚合pipeline
  • upsert:是否做更新插入操作
  • collation:指定排序规则
  • arrayFilters:数组筛选器,指定数组中要更新的元素的的条件
  • hint:指定更新要使用的索引,如果索引不存在,写入会报错

replaceOne操作

  1. db.collection.bulkWrite([
  2. { replaceOne :
  3. {
  4. "filter": <document>,
  5. "replacement": <document>,
  6. "upsert": <boolean>,
  7. "collation": <document>,
  8. "hint": <document|string>
  9. }
  10. }
  11. ] )
  • filter:用来过滤需要替换的数据
  • update:替换操作,这里是不包含update operators的Document
  • upsert:是否做更新插入操作
  • collation:指定排序规则
  • hint:指定更新要使用的索引,如果索引不存在,写入会报错

deleteOne操作

  1. db.collection.bulkWrite([
  2. { deleteOne : {
  3. "filter": <document>,
  4. "collation": <document>// Available starting in 3.4
  5. } }
  6. ] )
  • filter:用来过滤需要删除的数据
  • collation:指定排序规则

BulkWrite每组最大的操作数量不能超过maxWriteBatchSize(默认值是100000)的限制, 如果超过客户端程序会将他们拆分成多个小的批操作,同时如果批操作的操作太多,MongoDB会将错误消息截断成空字符串。

在分片集合上执行有序批操作会比普通集合更加耗时。

Capped集合限制

  • updateOne和updateMany操作,如果更新增加了文档的大小会抛出异常
  • replaceOne操作,如果新的文档大小比原始文档大,则会抛出异常
  • deleteOne和deleteMany操作不可以在Capped Collection使用,否则会抛出异常

Time Series集合限制

在时序集合上,BulkWrite操作只支持insertOne批操作,其他的都会抛出异常。

事务外的BulkWrite异常处理

在不考虑Write Concern报错下,错误会被写入writeErrors字段,有序操作在错误后停止,会写入第一个碰到的错误,无序操作则会写入批操作中的每个错误,一旦有错误发生,结果就不会显示插入_id的值,而是变成插入成功的数量。

事务内的BulkWrite异常处理

如果BulkWrite使用事务,write concern和事务不能产生冲突,并且不管Bulk是有序还是无序操作,只要碰到错误,整个批操作都会被回滚。

数据批量插入集合的建议

  • 预拆分集合,对于分片集合来说,假设集合为空的,该集合那就只有一个初始化块存在于一个单一分片上,MongoDB接收到数据以后需要对块进行拆分,并且分配到可用的分片上,为了提高性能我们可以预先拆分集合(后面单独说)
  • 尽量使用无序的BulkWrite操作
  • 避免单调递增,假设分片键是递增的,那么所有的数据插入都会进入集合的最后一个块,因此该集群的插入能力始终受到最后一个分片的限制,可以通过以下方法来进行优化:1.反转分片键的二进制位;2.交换分片键的前16位和后16 位

0 人点赞