使用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)
#  都无法实现批量插入, 如果是更新,只能更新一条数据,批量更新无法实现
三、bulk_write批量更新文档

Send a batch of write operations to the server.
Requests are passed as a list of write operation instances ( InsertOne, UpdateOne, UpdateMany, ReplaceOne, DeleteOne, or DeleteMany).

语法格式:bulk_write(requests, ordered=True, bypass_document_validation=False, session=None)


>>> from pymongo import InsertOne, DeleteOne, ReplaceOne,UpdateOne
>>> from pymongo import MongoClient
>>> db = MongoClient('mongodb://ip:27017').database
>>> db.count()
1
>>> list(db.find())
[{'_id': 'a', 'n': 'a'}]

#  UpdateOne 测试一下
>>> db.bulk_write([UpdateOne({"_id":"a"},{"$set":{"n":"aa"}}, upsert=True), UpdateOne({"_id":"b"},{"$set":{"n":"b"}}, upsert=True)])
>>> list(db.find())
[{'_id': 'a', 'n': 'aa'}, {'_id': 'b', 'n': 'b'}]
# 可以看到 记录 a 的 "n" 成功被更新为 "aa", 并且新增了一条记录 b



# ReplaceOne 测试一下
>>> db.bulk_write([ReplaceOne({"_id":"b"},{"n":"bb"}, upsert=True), ReplaceOne({"_id":"c"},{"n":"cc"}, upsert=True)])
>>> list(db.find())
[{'_id': 'a', 'n': 'aa'}, {'_id': 'b', 'n': 'bb'}, {'_id': 'c', 'n': 'cc'}]

# 总结:
# 可以看到, 记录 b 的 n 从 "b" 更新为 "bb", 并且新增了一条记录 c
# 这里需要注意的是, 如果使用 ReplaceOne, update 的值不能使用"$set"
# 注意区分 ReplaceOne 和 UpdateOne 的区别。加上$set后是更新操作. 没有$set 是覆盖操作。
四、$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)

更新前:
在这里插入图片描述
更新后:
在这里插入图片描述

<think>好的,用户想知道如何使用DataGrip在MongoDB中插入数据。首先,我需要回忆DataGrip的基本功能和MongoDB的操作方式。DataGrip是JetBrains的数据库管理工具,支持多种数据库,包括MongoDB。不过,MongoDB是NoSQL数据库,与传统的关系型数据库不同,使用文档存储结构。 接下来,插入数据MongoDB通常使用insert命令或者insertMany等方法。但在DataGrip中如何操作呢?可能用户习惯了图形界面,不太熟悉直接写脚本。首先需要确认DataGrip是否支持MongoDB的图形化插入。根据之前的引用资料,比如引用[3]提到用Python插入数据,但用户现在用的是DataGrip,可能需要通过查询控制台执行MongoDB的命令。 步骤可能包括:连接到MongoDB实例,选择数据库和集合,然后打开控制台输入插入命令。例如,使用db.collection.insert()或者insertMany。另外,引用[2]提到批量插入需要调用execute(),但这是否适用于DataGrip呢?可能需要测试一下。 另外,用户可能需要指导如何编写正确的MongoDB插入语句。例如,插入单个文档或批量插入。同时,注意DataGrip的界面是否有导入数据的功能,比如通过JSON文件导入,这可能也是插入数据的一种方式。 需要提醒用户注意语法是否正确,比如文档的JSON格式,键名是否用引号括起来,以及确保连接字符串正确,如引用[3]中的mongodb://localhost:27017/。最后,确保用户在执行插入操作后能够验证数据是否成功插入,比如通过查询集合来检查。</think>### 如何使用DataGrip在MongoDB中插入数据? #### 步骤说明 1. **连接MongoDB数据库** - 在DataGrip中新建数据源,选择MongoDB类型。 - 填写连接参数(主机、端口、认证信息等),格式参考:`mongodb://localhost:27017/`[^3]。 - 测试连接成功后保存配置。 2. **选择目标数据库和集合** - 在左侧数据库导航栏中,展开已连接的MongoDB实例,选择目标数据库(如`testdb`)。 - 右键点击目标集合(如`users`),选择 **Open Console** 打开查询控制台。 3. **编写插入语句** MongoDB插入语法示例: ```javascript // 插入单条文档 db.users.insert({ name: "Alice", age: 30, email: "alice@example.com" }); // 批量插入文档 db.users.insertMany([ { name: "Bob", age: 25 }, { name: "Charlie", age: 35 } ]); ``` - 使用`insert()`插入单条文档,`insertMany()`批量插入。 - 确保JSON格式正确(键名需用双引号包裹,值支持多种类型如字符串、数字、嵌套对象等)。 4. **执行并验证** - 在查询控制台中执行语句,观察输出结果是否包含`"acknowledged": true`。 - 右键点击集合,选择 **Refresh** 查看新插入的数据。 5. **通过UI界面直接插入(可选)** - 双击打开集合,点击表格视图的 **+** 按钮,手动输入字段值。 - 输入完成后按 **Ctrl+Enter**(Windows/Linux)或 **Cmd+Enter**(Mac)保存。 #### 注意事项 - **事务支持**:批量插入时,若需事务特性,可结合MongoDB的会话(Session)功能实现[^2]。 - **性能优化**:批量插入推荐使用`insertMany()`而非多次`insert()`,以减少网络开销[^1]。 - **错误处理**:插入时若主键(`_id`)冲突,操作会终止并抛出异常,需提前检查唯一性约束。 --- ### 相关问题 1. **如何在DataGrip中查询MongoDB数据?** 2. **MongoDB插入数据时如何避免重复文档?** 3. **DataGrip支持哪些其他NoSQL数据库的操作?** --- ### 引用说明 : MongoDB连接字符串格式和客户端配置说明。 : MongoDB批量操作(如`insertMany()`)的语法和执行要求。 [^3]: Python操作MongoDB的示例,间接验证连接参数的正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值