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

使用Pymongo执行Upsert:如何获取更新文档的_id?

关于Pymongo update_one获取更新文档_id的问题

问题重现

使用Pymongo操作MongoDB时,调用update_one并设置upsert=True会出现两种不同的返回结果:

  • 触发插入(upsert)行为时,UpdateResult的upserted_id会返回新插入文档的_id;
  • 更新现有文档时,upserted_id为None,仅raw_result返回更新统计信息(如{'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True})。

测试代码:

client = MongoClient(connection_uri)
database = client["example_db"]
collection = database["sample_collection"]

# 插入新文档(触发upsert)
result = collection.update_one(filter_query, update_operation, upsert=True)
print(result.upserted_id) # 返回新文档的_id

# 更新现有文档
result = collection.update_one(filter_query, update_operation, upsert=True)
print(result.upserted_id) # 输出None

print(result.raw_result) # {'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True}

这是正常行为,你没有遗漏

MongoDB原生的update命令本身不会返回被更新文档的_id,Pymongo的UpdateResult只是对MongoDB原始响应的封装,因此不会额外提供更新文档的_id字段。而upsert场景下返回upserted_id,是因为这个_id是插入操作生成的新值,属于插入响应的标准返回内容。

获取更新文档_id的正确方式

根据使用场景,有两种可行方案:

1. 直接复用查询条件中的_id

如果你的filter_query本身就包含目标文档的_id(比如{'_id': ObjectId('xxx')}),直接使用这个_id即可,无需额外获取。

2. 使用find_one_and_update方法

该方法会返回匹配的文档(默认返回更新前的版本,可通过参数设置返回更新后的版本),自然就能拿到文档的_id:

from pymongo import ReturnDocument

# 返回更新后的文档
updated_doc = collection.find_one_and_update(
    filter_query,
    update_operation,
    upsert=True,
    return_document=ReturnDocument.AFTER
)

if updated_doc:
    print(updated_doc['_id']) # 无论插入还是更新,都能拿到目标文档的_id

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:23:13