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

如何在PyMongo中执行带upsert=true的Update后获取记录的my_id

解决MongoDB Upsert后获取my_id的问题

嘿,我明白你的需求了——你想在执行upsert操作时,不管是插入了新记录还是命中了已存在的记录,都能拿到对应的my_id。原来的update方法返回的只是操作状态,所以你直接取status['my_id']肯定会报错,我给你两种解决方案,推荐第一种更高效的方式:

推荐方案:使用find_one_and_update(原子操作,一次搞定)

find_one_and_update是pymongo里更适合这种场景的方法,它可以在执行upsert的同时,直接返回操作后的文档(不管是新插入的还是已存在的)。

修改后的代码示例:

import pymongo
from pymongo import ReturnDocument

client = pymongo.MongoClient(settings.MONGO_DB_URI)
db = client[settings.MONGO_DB_NAME]

# 定义匹配条件
filter_query = {'my_id': '1234', 'name': 'alok'}
# 定义要插入的新记录内容
record_to_insert = {'my_id': '1234', 'name': 'alok', 'marks': 26}

# 执行upsert并返回操作后的文档
result_doc = db['mycollection'].find_one_and_update(
    filter_query,
    {'$setOnInsert': record_to_insert},
    upsert=True,
    return_document=ReturnDocument.AFTER  # 指定返回操作后的最新文档
)

# 直接从返回的文档中获取my_id
print('id is ', result_doc['my_id'])

为什么这个方法好用:

  • 它是原子操作:一次完成“查找匹配记录→不存在则插入→返回目标文档”的流程,避免了多步操作可能带来的并发问题。
  • ReturnDocument.AFTER确保你拿到的是最终状态的文档:如果是插入新记录,返回的就是刚插入的文档;如果是命中已有记录,返回的就是原有的匹配文档,两种情况都能直接拿到my_id。

备选方案:基于update结果二次查询(不推荐,效率低)

如果你坚持想用update方法,也可以通过返回的状态判断是插入还是已存在,再去查询对应的文档,但这种方式需要额外的查询操作,效率不如第一种:

代码示例:

import pymongo

client = pymongo.MongoClient(settings.MONGO_DB_URI)
db = client[settings.MONGO_DB_NAME]

filter_query = {'my_id': '1234', 'name': 'alok'}
record_to_insert = {'my_id': '1234', 'name': 'alok', 'marks': 26}

status = db['mycollection'].update(filter_query, {'$setOnInsert': record_to_insert}, upsert=True)

if status.get('upserted'):
    # 说明插入了新记录,通过upserted的_id去查询文档
    inserted_doc = db['mycollection'].find_one({'_id': status['upserted']})
    print('id is ', inserted_doc['my_id'])
else:
    # 说明记录已存在,直接用原filter查询
    existing_doc = db['mycollection'].find_one(filter_query)
    print('id is ', existing_doc['my_id'])

注意点:

这种方式在高并发场景下可能出现问题——比如在update和find_one之间,数据可能被其他操作修改,所以更推荐第一种原子操作的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:17:35