用批量写入代替单个写入

最开始,我的代码逻辑是这样的:

for uid, data in user_dict.items():
user_collection.insert_one({'uid':uid, 'user_data': data})

  

这种方法在数据量较小时可以很好的工作,但是当数据量非常大时,此种操作会非常慢,我们需要通过批量写入的方式来写入数据。

user_data = ({'uid': uid, 'user_data': data} for uid, data in user_dict.items())
user_collection.insert_many(user_data)

调整insert_many参数

再来看是否可以通过调整insert_many参数来进一步优化性能。

  • ordered: 这个参数为True时,迫使MongoDB按顺序同步插入数据;而如果为False,则MongoDB会并发的不按固定顺序进行批量插入。显然当我们对性能有要求时,将该参数设为False是非常必要的。
  • bypass_document_validation: MongoDB3.2之后加入了document validation功能,用于验证写入的文档是否符合collection制定的规则,具体可以参考reference中的链接。而既然是验证就肯定需要花费时间,当我们对性能有极致要求时,也可以将此参数设为True,从而越过验证,直接写入。
  • session: 关于session,请参考References中的Client Session链接。

修改后的代码如下:

 
user_data = ({'uid': uid, 'user_data': data} for uid, data in user_dict.items())
user_collection.insert_many(user_data, ordere=False, bypass_document_validation=True)

  

最终性能的提升是非常明显的,时间量级从天降为分钟。

批量更新

前面的例子在插入操作时非常有效,但是对于更新操作由于update_many无法针对每一个doc进行更新,如本例中针对每一个uid进行更新,那么就需要使用bulk_write操作。

bulk_write就是将多个请求压缩到一次,减少网络通信占比。

 
from pymongo import UpdateOne

update_operations = []
for uid, user_data in user_dict.items():
op = UpdateOne({'uid': uid}, {'$set': {'user_data': user_data}}, upsert=True)
update_operations.append(op) user_collection.bulk_write(update_operations, ordered=False, bypass_document_validation=True)

  

批量读取

批量读取我们可以使用$in操作符,但是需要注意的是如果$in针对的list过大,那么可能会导致报错pymongo.errors.DocumentTooLarge, 目前我的做法是将大的list分割成1000个一段,然后分段查询

 
list_length = len(uid_list)
iter_size = 1000
current = 0
while current < list_length:
end = current + iter_size
uid_segment = uid_list[current: end]
result_cursor = mongo_collection.find({"uid": {"$in": uid_segment}})
for user_info in result_cursor:
# do something
...
current = current + iter_size

  

异常处理

在实践过程中,会遇到异常的情况,尤其是写入的时候,可能由于各种原因导致写入失败,因此需要catch exception,并打印详细信息,如下:

    try:
user_collection.insert_many(
data_iter, ordered=False, bypass_document_validation=True)
except BulkWriteError as e:
lg.error(e.details)

  

References:

作者:geekpy
链接:https://www.jianshu.com/p/b85fa2147405
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

bulk_write&Replace_one的更多相关文章

  1. mongodb批量操作, bulk_write,

    需要批量操作时候,节省网络连接交互次数,可以使用 bulk_write. 设置ordered=False,因为批量操作中没有互相依赖关系,如果有前后顺序的互相依赖,需要设置为True. bed_typ ...

  2. mongo批量插入问题(insert_many,bulk_write),spark df转json传入mongo

    https://blog.csdn.net/nihaoxiaocui/article/details/95060906 https://xuexiyuan.cn/article/detail/173. ...

  3. pymongo 操作

    python 操作 mongoDB 模块 pymongo 安装方法 sudo pip3 install pymongo 操作步骤 1. 创建数据库连接对象 conn = pymonge.MomgoCl ...

  4. python操作mongodb之五大量写操作

    import pymongo #库名 db = pymongo.MongoClient('192.168.30.252',27017).bulk_example #test集合插入 db.test.i ...

  5. Debian/Ubuntu手动编译安装MongoDB C++11驱动及驱动测试

    本文章仅限cnblogs网站内转载!请某网站自觉,遵纪守法,尊重原创! 系统环境情况: 最小化.无桌面环境 新安装的Debian 8 Server 版本操作系统虚拟机一台 手动编译安装MongoDB ...

  6. Python与Mongodb交互

    MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案 MongoDB 将数据存储为一个文档,数据结构由键值 ...

  7. Flask 扩展 Flask-PyMongo

    安装 pip install Flask-PyMongo 初始化Pymongo实例 from flask import Flask from flask.ext.pymongo import PyMo ...

  8. [转]pymongo常用操作函数

    pymongo 是 mongodb 的 python Driver Editor.记录下学习过程中感觉以后会常用多一些部分,以做参考. 1. 连接数据库 要使用pymongo最先应该做的事就是先连上运 ...

  9. MongoDB 及 scrapy 应用

    0 1.Scrapy 使用 MongoDB https://doc.scrapy.org/en/latest/topics/item-pipeline.html#write-items-to-mong ...

随机推荐

  1. 第二个spring冲刺第4天

    今天,我们团队参考了其他团队的四则运算的程序,发现很多地方可以学习. 1.别人的界面比较唯美,我们做的有点粗糙,所以这个必须要改善. 2.别人的具有较多的功能,比如计时器,我们要效仿. 3.还有难度选 ...

  2. 人生第一次JAVA编程,电梯(并不算完成版),以及IDEA里使用git

    首先先说说Intellij IDEA与git的互联,首先在任意(我是在coding)gitlab里新建一个工程. 然后新建一个工程记得注明url和地址.名称等 如果无法创建,则需要指定git地址 创建 ...

  3. Python3的bytes和str之别

    Python3不会以任意隐式的方式混用str和bytes,正是这使得:两者的区分特别清晰,在使用Python时不能拼接字符串和字节包,也无法搜索字节包里面的字符串(反之亦然),也不能讲字符串传入参数为 ...

  4. [转帖]shell 中的>/dev/null 2>&1 是什么鬼?

    shell 中的>/dev/null 2>&1 是什么鬼? http://blog.jobbole.com/109355/ 背景 我们经常能在shell脚本中发现>/dev/ ...

  5. 【设计模式】—— 访问者模式Visitor

    前言:[模式总览]——————————by xingoo 模式意图 对于某个对象或者一组对象,不同的访问者,产生的结果不同,执行操作也不同.此时,就是访问者模式的典型应用了. 应用场景 1 不同的子类 ...

  6. Codeforces914G Sum the Fibonacci(FWT)

    FWT大杂烩.跟着模拟做很多次FWT即可. #include<iostream> #include<cstdio> #include<cmath> #include ...

  7. 51Nod 1384 全排列

    给出一个字符串S(可能有重复的字符),按照字典序从小到大,输出S包括的字符组成的所有排列.例如:S = "1312", 输出为:   1123 1132 1213 1231 131 ...

  8. 使用Ubuntu的Crontab定时任务需要注意的地方

    Ubuntu使用crontab定时任务  网上有很多教程,现在记录下我遇到的一些问题,需要注意的地方: 1.定时任务的日志存放路径 网上的说法:cron的日志存放在 /var/log/cron 里面 ...

  9. 【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)

    [BZOJ1444][JSOI2009]有趣的游戏(高斯消元,AC自动机) 题面 BZOJ 题解 先把\(AC\)自动机构建出来,最好构成\(Trie\)图.然后这样子显然是在一个有向图中有一堆概率的 ...

  10. 洛谷P3302 森林

    题意:给定森林,可以把两棵树连起来或者询问链上第k大. 解:启发式合并. 我一开始想到了启发式合并但是发现这样做之后一棵子树就不是一段连续的区间了,那就不能子树xxx了,很迷惘. 后来看了题解发现本来 ...