mongodb ISODate问题(大量数据update优化)

本文介绍了一种在MongoDB中高效批量转换ISO日期格式到北京时间并保存为字符串的方法。通过对比遍历更新、去重更新及利用bulk_write批量操作三种方式,展示了如何优化数据处理流程,显著提升效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

  上周有个需求,把mongodb中birthday (ISO日期格式) 转换成北京时间,并保存成string类型。

最初思路:

  遍历查找出的结果,逐个加8小时,然后通过_id逐个去update_one。但是发现这种方式效率太低了,一分钟才能更新一千五百条数据。

  

# -*- coding: utf-8 -*-
from pymongo import MongoClient
import time
import datetime


def init():
    myclient = MongoClient(host='*.*.*.*', port=27117)
    # admin为登陆校验库
    auth_db = myclient.admin
    auth_db.authenticate('admin', '1234')
    # 连接库
    mydb = myclient['SR_123']
    mycol = mydb['Data_170724145755025001_0305_copy4']
    print(time.time())
    count = 0
    # 只取有birthday的数据,且只返回_id和birthday
    for x in mycol.find({'birthday':{'$exists': True}},{'_id','birthday'}):
        count = count + 1
        print(count)
        _time = x.get('birthday')
        _time += datetime.timedelta(hours=8)
        timeStr = _time.strftime("%Y%m%d")
        _id = x.get('_id')
        query1 = {"_id": _id}
        newvalues = {"$set": {"birthdayStr": timeStr}}
        mycol.update_one(query1, newvalues)
    print(time.time())

init()
View Code

 

 

 

新的思路:  

  通过birthday去重,然后通过birthday去update_many。

 for x in mycol.find().distinct('birthday'):
        _time1 = x + datetime.timedelta(hours=8)
        timeStr = _time1.strftime("%Y%m%d")
        query1 = {"birthday": x}
        newvalues = {"$set": {"birthdayStr": timeStr}}
        mycol.update_many(query1, newvalues)

  

最终思路:

  利用mongodb 的批量操作bulk_write,并且控制每次批量的数量,避免拼接过长报错。最终发现这种方式,当数据多的时候,效率远比上面两种方式快。

# -*- coding: utf-8 -*-
from pymongo import MongoClient
from pymongo import UpdateOne
import time
import datetime



def init():
    myclient = MongoClient(host='*.*.*.*', port=27117)
    # admin为登陆校验库
    auth_db = myclient.admin
    auth_db.authenticate('admin', '1234')
    # 连接库
    mydb = myclient['SR_123']
    mycol = mydb['Data_170724145755025001_0305_copy4']
    print(time.time())
    testList = []
    i = 0
    aa=mycol.find({'birthday': {'$exists': True}},{'_id','birthday'})
    for x in aa:
        i = i + 1;
        _time = x.get('birthday')
        _time += datetime.timedelta(hours=8)
        try:
            timeStr = _time.strftime("%Y%m%d")
        except:
            print(x)
        _id = x.get('_id')
        query1 = {"_id": _id}
        newvalues = {"$set": {"birthdayStr": r''+timeStr}}
        op = UpdateOne(query1, newvalues, upsert=True)
        testList.append(op)
        if( i % 50 == 0):
            print(i)
            mycol.bulk_write(testList, ordered=False, bypass_document_validation=True)
            testList.clear()


init()

  

 

转载于:https://www.cnblogs.com/cjh1111/p/10751845.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值