Mongodb批量写入操作bulkWrite()

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第76篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关注威赞。谢谢。

概述

Mongodb提供了针对单一集合写操作批量执行的方法。在批量写操作当中,Mongodb也允许用户自由定义数据提交的方式。通过db.collection.bulkWrite()方法,用户能够对单一集合进行数据插入,更新和删除操作 。当然, 方法db.collection.insertMany()也是一种批量写入操作。

批量写操作的顺序

用户定义的批量操作,可以是顺序执行的,也可以不按照顺序执行。

在顺序执行操作当中,Mongodb按照用户定义的批量操作序列,一步一步的执行。当某一个写操作出现错误时,mongdb会退出当前执行序列,不再执行后续的操作。而在非顺序执行操作当中,Mongodb并行执行用户定义的每一个操作。在非顺序执行操作当中,任意一个操作出错不会影响其他操作的执行。

在分片集合当中,顺序执行操作会比非顺序执行操作慢。因为需要等待前面的步骤完成。

bulkWrite()操作,默认是顺序执行每一个操作。用户如果需要指定非顺序执行,需要在options中定义{ordered: false}

支持批量写入的方法

bulkWrite支持下面的几个方法, 每一个方法都按照文档的形式 定义在bulkWrite操作的过程数据中。

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

应用

构建pizza文档并插入数据

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
}])

构建批量数据更新语句,要求完成下面几个动作

  • 向集合中插入两条新数据

  • 更新cheese文档的价格

  • 删除pepperoni

  • 将vegan替换成新的文档tofu

    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 )
    }

分片集中批量写入策略

在分片集中,大量的写入操作包括数据初始化,导入数据等可能会影响分片集的性能。因此,批量写入操作,可以考虑下面的策略

提前分片

mongodb中,空数据集只有一个初始数据块,放在单个分片当中。插入数据时,mongodb需要在接收数据,创建数据分块,将数据分块写入分片上消耗大量的时间。为了避免数据分块消耗的时间,用户可以提前将数据分好。

非顺序写入

为了在分片集中提高写入效率 ,用户可以将bulkWrite()方法的ordered参数设置为false。这样mongos可以尝试同时向多个分片写入数据。

避免在分片集中使用单调主键

如果片键在一次插入过程中单调递增,那么所有插入的数据都会进入集合的最后一个块,而这个块总是会出现在一个片上。因此,集群的插入容量永远不会超过该单个分片的插入容量。如果插入数据量大于单个分片所能处理的数据量,并且无法避免片键的单调递增,那么可以考虑对应用进行以下修改。反转片键的二进制位。这样可以保留信息,并避免将插入顺序与值的递增顺序关联起来。交换第一个和最后一个16位的单词来"打乱"插入操作。

相关推荐
The_Ticker1 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
Elastic 中国社区官方博客1 小时前
Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
企鹅侠客1 小时前
ETCD调优
数据库·etcd
Json_181790144801 小时前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
煎饼小狗1 小时前
Redis五大基本类型——Zset有序集合命令详解(命令用法详解+思维导图详解)
数据库·redis·缓存
永乐春秋2 小时前
WEB-通用漏洞&SQL注入&CTF&二次&堆叠&DNS带外
数据库·sql
打鱼又晒网2 小时前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
大白要努力!2 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
tatasix3 小时前
MySQL UPDATE语句执行链路解析
数据库·mysql
南城花随雪。3 小时前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库