暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MongoDB Bulk Write Operations

258



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 位

文章转载自程序员修炼笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论