数据库集合中有个字段是短信价格(单价*计费条数),经常会需要修改历史短信价格,由于数据量比较大(百万或者千万级别),for循环一条一条更新则速度非常慢。可使用下面脚本批量更新:
python
from pymongo import MongoClient, UpdateOne
# ------------------ 配置 MongoDB ------------------
username = "xxxx"
password = "xxxx"
host = "172.16.xxx.xxx"
port = 27017
db_name = "sms"
collection_name = "sms_record"
client = MongoClient(
host=host,
port=port,
username=username,
password=password,
authSource=db_name
)
db = client[db_name]
smsRecord = db[collection_name]
# ------------------ 查询条件 ------------------
startPt = "20260101"
endPt = "20260107"
appId = 123456
query = {"pt": {'$gte': startPt, "$lte": endPt}, "appId": appId}
# ------------------ 批量更新设置 ------------------
batch_size = 1000 # 每批处理多少条
operations = []
updated_count = 0
smsPrice = 0.03 # 标准单价
# ------------------ 遍历并准备批量操作 ------------------
for item in smsRecord.find(query, no_cursor_timeout=True):
sid = item['sid']
amount = item['amount']
fee = item['fee']
if float(fee) / float(amount) == smsPrice:
continue # 已是标准单价,不需要更新
print(item)
new_fee = smsPrice * amount
operations.append(UpdateOne({'sid': sid}, {'$set': {'fee': new_fee}}))
updated_count += 1
# 达到批量大小就提交一次
if len(operations) >= batch_size:
smsRecord.bulk_write(operations)
print(f"已更新 {updated_count} 条记录")
operations = []
# ------------------ 提交剩余未提交的操作 ------------------
if operations:
smsRecord.bulk_write(operations)
print(f"已更新 {updated_count} 条记录")
print(f"批量更新完成,总共更新 {updated_count} 条记录")