当前位置: 首页> 汽车> 行情 > MongoDB CRUD操作:批量写操作

MongoDB CRUD操作:批量写操作

时间:2025/7/11 17:32:20来源:https://blog.csdn.net/superatom01/article/details/139380356 浏览次数: 0次

MongoDB CRUD操作:批量写操作

文章目录

  • MongoDB CRUD操作:批量写操作
    • 关于批量操作的顺序
    • bulkWrite()支持的方法
    • 举例
    • 向分片集合批量插入的策略
      • 预分割集合
      • 无序写入 mongos
      • 避免单调节流

MongoDB提供了批量执行写入操作的能力,但批量写入操作只影响单个集合, MongoDB允许应用程序确定批量写入操作所需的可接受的确认级别。
db.collection.bulkWrite()方法支持批量插入、更新和删除的操作。当然,通过 db.collection.insertMany()方法也可以进行批量插入的操作。

关于批量操作的顺序

批量写入操作可以是有序的,也可以是无序的。通过操作的有序列表,MongoDB串行执行操作。如果在处理其中一个写操作期间发生错误,MongoDB 将返回,而不处理列表中任何剩余的写操作。

对于无序列表的操作,MongoDB可以并行执行操作,但不能保证这种行为。如果在处理其中一个写操作的过程中发生错误,MongoDB将继续处理列表中剩余的写操作。

在分片集合上执行有序操作列表通常会比执行无序列表慢,因为使用有序列表时,每个操作都必须等待前一个操作完成。

默认情况下,bulkWrite()执行有序操作,如果要指定无序写入操作,可以选项文档中设置ordered: false

bulkWrite()支持的方法

bulkWrite()支持下面的写操作:

  • insertOne
  • updateOne
  • updateMany
  • replaceOne
  • deleteOne
  • deleteMany

所有的写操作都作为数组中的文档传递给bulkWrite()

举例

使用下面的脚本创建pizzas集合:

db.pizzas.insertMany( [{ _id: 0, type: "pepperoni", size: "small", price: 4 },{ _id: 1, type: "cheese", size: "medium", price: 7 },{ _id: 2, type: "vegan", size: "large", price: 8 }
] )

下面的bulkWrite()示例在pizzas集合上运行:

  • 使用insertOne添加两个文档
  • 使用updateOne更新一个文档
  • 使用deleteOne删除一个文档
  • 使用replaceOne替换一个文档
try {db.pizzas.bulkWrite( [{ insertOne: { document: { _id: 3, type: "beef", size: "medium", price: 6 } } },{ insertOne: { document: { _id: 4, type: "sausage", size: "large", price: 10 } } },{ updateOne: {filter: { type: "cheese" },update: { $set: { price: 8 } }} },{ deleteOne: { filter: { type: "pepperoni"} } },{ replaceOne: {filter: { type: "vegan" },replacement: { type: "tofu", size: "small", price: 4 }} }] )
} catch( error ) {print( error )
}

执行完成后输出已完成操作的摘要信息:

{acknowledged: true,insertedCount: 2,insertedIds: { '0': 3, '1': 4 },matchedCount: 2,modifiedCount: 2,deletedCount: 1,upsertedCount: 0,upsertedIds: {}
}

向分片集合批量插入的策略

大量插入操作(包括初始数据插入或常规数据导入)可能会影响分片集群的性能。对于批量插入,可考虑以下策略:

预分割集合

如果分片集合为空,则该集合只有一个初始块,该块驻留在单个分片上,MongoDB必须花时间接收数据、创建拆分并将拆分块分发到可用分片。为了避免这种性能成本,可以预先拆分集合。

无序写入 mongos

要提高分片集群的写入性能,可以使用bulkWrite()``,并将可选参数ordered设置为false。 mongos可以尝试同时将写入发送到多个分片。对于空集合,首先按照分片集群中的分割块中的描述预先分割集合。

避免单调节流

如果分片键在插入期间单调增加,则所有插入的数据都会到达集合中的最后一个块,该块将始终位于单个分片上。因此,集群的插入容量永远不会超过单个分片的插入容量。

如果插入量大于单个分片可以处理的量,并且无法避免单调递增的分片键,则建议对应用程序进行以下修改:

  • 反转片键的二进制位。这保留了信息并避免将插入顺序与递增的值序列相关联。
  • 交换第一个和最后一个 16 位字以“随机”插入。

以下示例采用 C++ 语言,交换生成的 BSON ObjectId 的前导和尾随 16 位字,以便它们不再单调递增。

using namespace mongo;
OID make_an_id() {OID x = OID::gen();const unsigned char *p = x.getData();swap( (unsigned short&) p[0], (unsigned short&) p[10] );return x;
}void foo() {// 创建一个对象BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "name" << "jane" );
}
关键字:MongoDB CRUD操作:批量写操作

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: