You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python异步MongoDB客户端Motor中使用findAndModify?

如何在Motor中使用findAndModify命令

PyMongo提供了现成的find_and_modify()方法,但Motor没有对应的异步封装,不过可以通过Motor的run_command()方法异步执行MongoDB原生的findAndModify命令,实现相同的功能。

以下是几种常见场景的示例:

1. 修改匹配文档并返回原文档(默认行为)

当需要找到符合条件的文档、执行更新操作,并返回更新前的原文档时,可使用如下代码:

import asyncio
import motor.motor_asyncio

async def modify_and_get_old_doc():
    # 初始化异步客户端
    client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017')
    db = client.test_db
    
    # 执行findAndModify命令
    result = await db.command({
        'findAndModify': 'test_collection',  # 指定操作的集合名
        'query': {'status': 'active'},       # 匹配条件
        'update': {'$set': {'status': 'processed'}},  # 更新操作
        'sort': {'created_at': -1}           # 多个匹配时,按created_at倒序取第一个
    })
    
    # 获取返回的原文档(无匹配则返回None)
    print("原文档:", result.get('value'))

asyncio.run(modify_and_get_old_doc())

2. 修改并返回更新后的新文档

如果需要返回更新后的文档,只需添加'new': True参数:

import asyncio
import motor.motor_asyncio

async def modify_and_get_new_doc():
    client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017')
    db = client.test_db
    
    result = await db.command({
        'findAndModify': 'test_collection',
        'query': {'_id': 123},
        'update': {'$inc': {'views': 1}},    # 自增views字段
        'new': True                          # 返回更新后的文档
    })
    
    print("更新后的文档:", result.get('value'))

3. 无匹配则插入新文档(Upsert)

当需要实现"有则更新,无则插入"的逻辑时,添加'upsert': True参数:

import asyncio
import datetime
import motor.motor_asyncio

async def upsert_example():
    client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017')
    db = client.test_db
    
    result = await db.command({
        'findAndModify': 'test_collection',
        'query': {'user_id': 456},
        # 插入时设置created_at,更新时自增login_count
        'update': {'$setOnInsert': {'created_at': datetime.datetime.now()}, '$inc': {'login_count': 1}},
        'new': True,
        'upsert': True                       # 无匹配时插入新文档
    })
    
    print("结果文档:", result.get('value'))

注意事项

  • MongoDB原生命令是驼峰式的findAndModify,不要写成PyMongo风格的下划线格式find_and_modify
  • 若没有匹配到任何文档,result.get('value')会返回None
  • 所有操作必须使用await调用,因为Motor是异步驱动
  • 还可添加其他参数,比如fields指定返回的字段,remove: True实现删除匹配文档的功能(类似find_one_and_delete)

内容的提问来源于stack exchange,提问作者andre487

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:39:34