- MongoDB CRUD 操作 >
- CRUD 概念 >
- 写操作 >
- MongoDB中的批量插入
MongoDB中的批量插入¶
在一些情况下,您也许需要将大量数据中插入或者摄取到MongoDB数据库中。 批量插入 拥有一些不同于与其它写操作的特殊考量。
使用 insert() 方法¶
当参数传递的是大量文档时, insert() 方法将会执行一个批量插入操作,并且原子性地插入每个文档。通过分摊 write concern 的开销,批量插入将会显著提高性能。
在 drivers 中,您可以对写关注进行批量配置而不一定限制于每个文档的级别。
驱动器在它们的插入操作中拥有一个 ContinueOnError 选项,因此即使某个插入操作失败了,该批量操作仍然可以继续插入剩余文档。
注解
在一个批量插入的过程中,如果出现了多个错误,客户端将只会收到最后的产生的错误。
参见
请查阅 Driver documentation 及 导入导出MongoDB数据 以了解关于在应用中执行批量插入操作的更多细节。
分片集群上的批量插入¶
在未分片的集群中, ContinueOnError 是可选的配置,但是在一个 分片集合 上所有的批量操作都会在 ContinueOnError 的配置下运行,该选项上不能被禁止的。
大量的批量插入操作,包括初始的数据插入或者常规数据导入,都将会影响 分片集群 的性能。针对批量插入,考虑以下策略:
预先分割集合¶
如果该分片集合为空,那么该集合就只有一个初始的、位于单一分片上的 数据段 。MongoDB就必须花时间来接收数据、建立分割,再将这些分割好的数据段分发到可用的分片上。为了避免性能的消耗,您可以根据 在集群中分裂数据块 中所描述的,对集合进行预分割。
减少单调节流¶
如果您的片键在一个插入中单调递增,这就意味中所有插入的数据都到了集合中最后一个数据段,这些数据将经常落在一个单一的分片中。因此,集群的插入容量将永远都不会超过该单一分片的插入容量。
如果您的插入量超过了一个单一分片可处理的范围,并且不能避免片键的单调递增,您可以考虑对应用进行下面的修改:
颠倒片键的二进制位。这样做可以保留相关信息,并且避免了将插入顺序和序列值的增加相对应。
交换前16位和后16位来 “重排” 插入。
示例
The following example, in C++, swaps the leading and trailing 16-bit word of BSON ObjectIds generated so that they are no longer monotonically increasing.
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() {
// create an object
BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "name" << "jane" );
// now we may insert o into a sharded collection
}
参见
您可以通过查阅 片键 以及 Shard Key Internals (特别是 选择一个片键 )来了解更多关于选择片键的信息。