使用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
相关产品推荐
相关产品推荐

