MongoDB 4.2.15 带聚合管道的upsert更新时如何返回文档_id
解决方案
MongoDB 原生的 update 命令默认仅在 upsert 插入新文档时返回生成的 _id,纯更新场景确实不会携带被修改文档的 _id 字段,你可以通过调整调用方法实现需求:
1. 改用 findOneAndUpdate 方法(最优方案,适配你当前4.2版本)
该方法支持传入聚合管道作为更新逻辑,和你现有写法的兼容性极高,同时可以配置返回更新后的完整文档,直接就能拿到_id,参考写法如下:
db.collectionName.findOneAndUpdate( { /* 替换为你原有update操作中q字段的查询条件 */ }, [ // 原有u字段中的聚合管道直接复用即可 { "$project": { ... } }, { "$set": { ... } }, { "$set": { ... } }, { "$project": { ... } } ], { upsert: true, returnNewDocument: true, // 必须配置,返回更新/插入后的最新文档 // 可选配置:如果只需要_id字段可以加下行,不需要就删除,返回完整文档 projection: { "_id": 1 } } )
2. 结果说明
- 触发插入场景:返回值为新创建的文档,直接取值
_id即可,和你之前从upserted字段拿的结果完全一致 - 触发更新场景:返回值为更新后的目标文档,同样可以直接获取
_id字段
3. 其他场景适配
如果你后续需要调整为批量更新(multi=true),可以选择两种方案:
- 把批量操作拆分为多条单条更新,依次调用
findOneAndUpdate拿每个文档的_id - 执行完批量update后,用相同的查询条件再执行一次find查询,批量获取匹配文档的
_id
内容的提问来源于stack exchange,提问作者gunboxer
相关产品推荐
相关产品推荐

