Upsert 操作指南 - 不存在就插入,存在则更新
📋 快速回答
实现"不存在就插入,存在则更新"使用以下方法:
⭐ 推荐方法:findOneAndUpdate() + upsert: true
🎯 所有支持 Upsert 的方法
💡 详细用法
关于
updateMany()upsert:MongoDB 支持updateMany(filter, update, { upsert: true }),但无匹配分支只会基于filter和update插入一个文档。它不是“按输入列表逐条 upsert”。多条独立 key 的 upsert 请优先循环调用upsertOne(),或使用原生bulkWrite的updateOne+upsert: true。
1. findOneAndUpdate() - 推荐 ⭐⭐⭐⭐⭐
优势:
- ✅ 原子操作
- ✅ 返回文档内容
- ✅ 可以获取插入的 _id
- ✅ 支持
$setOnInsert
基本用法:
获取是否为新插入:
2. updateOne() - 简单场景 ⭐⭐⭐⭐
优势:
- ✅ 性能好(不返回文档)
- ✅ 返回操作统计
基本用法:
3. replaceOne() - 替换整个文档 ⭐⭐
优势:
- ✅ 完全替换文档(不使用更新操作符)
用法:
🎯 常见使用场景
场景 1:用户配置
场景 2:计数器
场景 3:商品库存
场景 4:缓存管理
场景 5:每日签到
⚠️ 重要注意事项
1. 必须使用更新操作符
2. $setOnInsert 的使用
$setOnInsert 只在 插入新文档 时生效:
3. 唯一索引冲突
📊 性能对比
🎯 最佳实践
1. 优先使用 findOneAndUpdate()
大多数情况下推荐使用,因为:
- 可以获取文档内容
- 支持
$setOnInsert - 原子操作保证
2. 性能优化场景使用 updateOne()
如果只需要知道是否成功: