使用python实现Mongo批量操作数据, Mongo — python使用update_many方法

使用python实现Mongo批量操作数据

一、数据库连接

from pymongo import MongoClient

1、有密码
db = MongoClient('mongodb://ip:27017').database
db.authenticate('username',password='password')
或者
db = MongoClient('mongodb://username:password@ip:port').database.table

2、无密码
db = MongoClient('mongodb://ip:27017').database

二、insert_many批量插入文档

# insert_many 用法
语法格式:insert_many(documents, ordered=True, bypass_document_validation=False)


>>> db.test.count_documents({})
0
>>> result = db.test.insert_many([{'x': i} for i in range(2)])
>>> result.inserted_ids
[ObjectId('54f113fffba522406c9cc20e'), ObjectId('54f113fffba522406c9cc20f')]
>>> db.test.count_documents({})
2


备注:
insert_many(docs, ordered=True)  # 遇到错误 break, 并且抛出异常
insert_many(docs, ordered=False) # 遇到错误 continue, 循环结束后抛出异常
# 无论 ordered 是 True 或者 False, 批量添加的时候遇到重复的, 并不会对历史数据更新

补充:

insert_one(document, bypass_document_validation=False)
replace_one(filter, replacement, upsert=False, bypass_document_validation=False, collation=None)
update_one(filter, update, upsert=False, bypass_document_validation=False, collation=None)
update_many(filter, update, upsert=False, bypass_document_validation=False, collation=None)
#  都无法实现批量插入, 如果是更新,只能更新一条数据,批量更新无法实现

四、$setOnInsert插入不存在的数据

# 以下不能实现主键存在的情况下对数据进行更新
bulk = pymongo.bulk.BulkOperationBuilder(collection,ordered=True)
for doc in docs:
    bulk.find({ "_id": doc["_id"] }).upsert().updateOne({
        "$setOnInsert": doc
    })
response = bulk.execute()

# 主键已存在时, 对数据进行更新. 主键不在表中的时候对数据进行插入操作。并且, 如果要插入的数据没有设置主键 _id, 进行普通的插入操作即可。
def insert_many(collection, docs=None, update=True):
    if not docs:
        return
    # $set 的时候, 会更新数据, setOnInsert只插入不更新
    update_key = "$set" if update else "$setOnInsert"
    bulk = BulkOperationBuilder(collection, ordered=False)
    for i in docs:
        if i["_id"]:
            bulk.find({"_id":i["_id"]}).upsert().update_one({update_key:i })
        else:
            bulk.insert(i)
    result = bulk.execute()
    modify_count = result.get("nModified")
    insert_count = result.get("nUpserted") + result.get("nInserted")

五、示例

我们这边有个需求是从excel中读取商品数据,然后进行批量更新

#!/usr/bin/env python
#-*- coding:utf-8 -*-
from pymongo import MongoClient
import pandas as pd
from pymongo import UpdateOne

#定义两个列表
raw_datas = []     #原始数据
update_datas = []  #更新后数据

#连接mongo服务器
mongo = MongoClient('mongodb://127.0.0.1').pms.product

#从excel中获取要更新的数据
df = pd.read_excel('test.xlsx')
for i in df['name']:
    raw_datas.append({'myquery':{'name':'%s' %i,'companyId':28}} )

#从数据库查出要修改的数据,并更新字段
for datas in raw_datas:
    get_data = mongo.find(datas.get('myquery'))
    for data in get_data:
        data['detail']['ownership'] = 'STORE'
        datas.update({'detail':data['detail']})

#替格式[UpdateOne({"_id":"a"},{"$set":{"n":"aa"}}, upsert=True), UpdateOne({"_id":"b"},{"$set":{"n":"b"}}, upsert=True)]
for line in raw_datas:
    update_datas.append(UpdateOne(line.get('myquery'),{'$set':{'detail':line.get('detail')}},upsert=True))

#批量更新
mongo.bulk_write(update_datas)

参考 https://blog.csdn.net/m0_37886429/article/details/93480363?

Mongo — python使用update_many方法

mongo集合中

  • 可以看到name字段的值存在两个c开头

代码演示

  • 使用正则
  • 查询到集合中name字段的值是c开头的数据,再把age字段的值设为100
# -*- coding: utf-8 -*-
# @Author   : zbz

from pymongo import MongoClient


def main():
    client = MongoClient()
    users_coll = client["data"]["users"]

    query = {"name": {"$regex": "^c"}}
    update = {"$set": {"age": 100}}
    users_coll.update_many(query, update)


if __name__ == '__main__':
    main()

再来看mongo集合

  • 在字段name的值是c开头的数据中,age字段的值变成100

参考 https://blog.csdn.net/MarkAdc/article/details/118089224?o

您可能还喜欢...

发表回复