MongoDB文档更新 #
一、更新概述 #
1.1 更新类型 #
MongoDB提供三种更新方式:
| 方法 | 说明 |
|---|---|
| updateOne | 更新单个文档 |
| updateMany | 更新多个文档 |
| replaceOne | 替换整个文档 |
1.2 更新操作符 #
javascript
// 更新操作符
{
$set: { ... }, // 设置字段
$unset: { ... }, // 删除字段
$inc: { ... }, // 增加数值
$push: { ... }, // 添加数组元素
$pull: { ... } // 删除数组元素
}
二、updateOne方法 #
2.1 基本更新 #
javascript
// 更新单个文档
db.users.updateOne(
{ name: "John" }, // 过滤条件
{ $set: { age: 26 } } // 更新操作
)
// 输出
{
"acknowledged": true,
"matchedCount": 1,
"modifiedCount": 1
}
2.2 更新多个字段 #
javascript
// 更新多个字段
db.users.updateOne(
{ name: "John" },
{
$set: {
age: 26,
email: "john.new@example.com",
city: "Shanghai"
}
}
)
2.3 更新嵌套字段 #
javascript
// 更新嵌套字段
db.users.updateOne(
{ name: "John" },
{
$set: {
"address.city": "Shanghai",
"address.zipCode": "200000"
}
}
)
2.4 更新数组元素 #
javascript
// 更新数组元素(按索引)
db.users.updateOne(
{ name: "John" },
{ $set: { "hobbies.0": "reading" } }
)
// 更新数组元素(按条件)
db.users.updateOne(
{ name: "John", "scores.type": "math" },
{ $set: { "scores.$.value": 95 } }
)
2.5 更新选项 #
javascript
// 更新选项
db.users.updateOne(
{ name: "John" },
{ $set: { age: 26 } },
{
upsert: true, // 不存在则插入
writeConcern: { w: "majority" }
}
)
三、updateMany方法 #
3.1 批量更新 #
javascript
// 更新多个文档
db.users.updateMany(
{ status: "inactive" }, // 过滤条件
{ $set: { status: "active" } } // 更新操作
)
// 输出
{
"acknowledged": true,
"matchedCount": 10,
"modifiedCount": 10
}
3.2 条件更新 #
javascript
// 条件更新
db.users.updateMany(
{ age: { $lt: 18 } },
{ $set: { status: "minor" } }
)
// 复杂条件更新
db.orders.updateMany(
{
status: "pending",
createdAt: { $lt: new Date("2024-01-01") }
},
{ $set: { status: "expired" } }
)
3.3 数组更新 #
javascript
// 更新数组中的所有匹配元素
db.users.updateMany(
{ "scores.type": "math" },
{ $set: { "scores.$[].passed": true } }
)
// 使用$[]更新所有元素
db.users.updateMany(
{ name: "John" },
{ $inc: { "scores.$[]": 5 } }
)
四、replaceOne方法 #
4.1 替换文档 #
javascript
// 替换整个文档(保留_id)
db.users.replaceOne(
{ name: "John" },
{
name: "John Doe",
email: "john.doe@example.com",
age: 30,
city: "Shanghai"
}
)
// 输出
{
"acknowledged": true,
"matchedCount": 1,
"modifiedCount": 1
}
4.2 替换与更新的区别 #
javascript
// updateOne:只更新指定字段
db.users.updateOne(
{ name: "John" },
{ $set: { age: 26 } }
)
// 其他字段保持不变
// replaceOne:替换整个文档
db.users.replaceOne(
{ name: "John" },
{ name: "John", age: 26 }
)
// 其他字段被删除(除了_id)
五、更新操作符 #
5.1 字段操作符 #
$set - 设置字段值
javascript
// 设置字段
db.users.updateOne(
{ name: "John" },
{ $set: { age: 26, city: "Shanghai" } }
)
// 设置嵌套字段
db.users.updateOne(
{ name: "John" },
{ $set: { "address.city": "Shanghai" } }
)
$unset - 删除字段
javascript
// 删除字段
db.users.updateOne(
{ name: "John" },
{ $unset: { middleName: "" } }
)
// 删除嵌套字段
db.users.updateOne(
{ name: "John" },
{ $unset: { "address.zipCode": "" } }
)
$inc - 增加数值
javascript
// 增加数值
db.users.updateOne(
{ name: "John" },
{ $inc: { age: 1 } }
)
// 减少数值
db.users.updateOne(
{ name: "John" },
{ $inc: { balance: -100 } }
)
// 增加多个字段
db.users.updateOne(
{ name: "John" },
{ $inc: { age: 1, score: 10 } }
)
$mul - 乘法
javascript
// 乘法运算
db.products.updateOne(
{ name: "Product A" },
{ $mul: { price: 1.1 } } // 价格增加10%
)
$rename - 重命名字段
javascript
// 重命名字段
db.users.updateOne(
{ name: "John" },
{ $rename: { "oldName": "newName" } }
)
$setOnInsert - 插入时设置
javascript
// 仅在插入时设置字段
db.users.updateOne(
{ name: "John" },
{
$set: { age: 26 },
$setOnInsert: { createdAt: new Date() }
},
{ upsert: true }
)
$currentDate - 设置当前日期
javascript
// 设置当前日期
db.users.updateOne(
{ name: "John" },
{ $currentDate: { updatedAt: true } }
)
// 设置时间戳
db.users.updateOne(
{ name: "John" },
{ $currentDate: { lastModified: { $type: "timestamp" } } }
)
$min - 最小值
javascript
// 如果新值小于当前值则更新
db.products.updateOne(
{ name: "Product A" },
{ $min: { price: 50 } }
)
$max - 最大值
javascript
// 如果新值大于当前值则更新
db.products.updateOne(
{ name: "Product A" },
{ $max: { price: 100 } }
)
5.2 数组操作符 #
$push - 添加元素
javascript
// 添加单个元素
db.users.updateOne(
{ name: "John" },
{ $push: { hobbies: "reading" } }
)
// 添加多个元素
db.users.updateOne(
{ name: "John" },
{ $push: { hobbies: { $each: ["reading", "swimming"] } } }
)
// 添加并排序
db.users.updateOne(
{ name: "John" },
{
$push: {
scores: {
$each: [85, 90, 78],
$sort: -1,
$slice: 10 // 只保留前10个
}
}
}
)
// 添加到指定位置
db.users.updateOne(
{ name: "John" },
{
$push: {
scores: {
$each: [95],
$position: 0 // 插入到开头
}
}
}
)
$pull - 删除元素
javascript
// 删除匹配元素
db.users.updateOne(
{ name: "John" },
{ $pull: { hobbies: "reading" } }
)
// 删除多个元素
db.users.updateOne(
{ name: "John" },
{ $pull: { scores: { $lt: 60 } } } // 删除小于60的分数
)
// 删除嵌套数组元素
db.users.updateOne(
{ name: "John" },
{ $pull: { "comments": { userId: 123 } } }
)
$pullAll - 删除多个值
javascript
// 删除多个指定值
db.users.updateOne(
{ name: "John" },
{ $pullAll: { hobbies: ["reading", "swimming"] } }
)
$pop - 删除首尾元素
javascript
// 删除最后一个元素
db.users.updateOne(
{ name: "John" },
{ $pop: { hobbies: 1 } }
)
// 删除第一个元素
db.users.updateOne(
{ name: "John" },
{ $pop: { hobbies: -1 } }
)
$addToSet - 添加唯一元素
javascript
// 添加唯一元素(已存在则不添加)
db.users.updateOne(
{ name: "John" },
{ $addToSet: { hobbies: "reading" } }
)
// 添加多个唯一元素
db.users.updateOne(
{ name: "John" },
{ $addToSet: { hobbies: { $each: ["reading", "swimming"] } } }
)
$each - 批量操作
javascript
// 与$push配合使用
db.users.updateOne(
{ name: "John" },
{ $push: { scores: { $each: [85, 90, 78] } } }
)
// 与$addToSet配合使用
db.users.updateOne(
{ name: "John" },
{ $addToSet: { tags: { $each: ["tag1", "tag2"] } } }
)
$sort - 数组排序
javascript
// 数组排序
db.users.updateOne(
{ name: "John" },
{
$push: {
scores: {
$each: [],
$sort: -1
}
}
}
)
$slice - 限制数组长度
javascript
// 限制数组长度
db.users.updateOne(
{ name: "John" },
{
$push: {
logs: {
$each: ["log1", "log2"],
$slice: -10 // 只保留最后10个
}
}
}
)
$position - 指定位置插入
javascript
// 在指定位置插入
db.users.updateOne(
{ name: "John" },
{
$push: {
scores: {
$each: [95],
$position: 0
}
}
}
)
5.3 位操作符 #
$bit - 位运算
javascript
// 位与运算
db.users.updateOne(
{ name: "John" },
{ $bit: { flags: { and: 5 } } }
)
// 位或运算
db.users.updateOne(
{ name: "John" },
{ $bit: { flags: { or: 1 } } }
)
// 位异或运算
db.users.updateOne(
{ name: "John" },
{ $bit: { flags: { xor: 3 } } }
)
六、upsert操作 #
6.1 基本upsert #
javascript
// upsert:不存在则插入
db.users.updateOne(
{ name: "John" },
{ $set: { age: 26 } },
{ upsert: true }
)
// 输出
{
"acknowledged": true,
"matchedCount": 0,
"modifiedCount": 0,
"upsertedId": ObjectId("...")
}
6.2 条件upsert #
javascript
// 条件upsert
db.users.updateOne(
{ email: "john@example.com" },
{
$set: { name: "John", age: 26 },
$setOnInsert: { createdAt: new Date() }
},
{ upsert: true }
)
6.3 批量upsert #
javascript
// 批量upsert
db.users.bulkWrite([
{
updateOne: {
filter: { name: "John" },
update: { $set: { age: 26 } },
upsert: true
}
},
{
updateOne: {
filter: { name: "Jane" },
update: { $set: { age: 28 } },
upsert: true
}
}
])
七、findAndModify #
7.1 findOneAndUpdate #
javascript
// 查找并更新
db.users.findOneAndUpdate(
{ name: "John" },
{ $set: { age: 26 } },
{
returnNewDocument: true, // 返回更新后的文档
sort: { age: -1 },
upsert: true
}
)
7.2 findOneAndReplace #
javascript
// 查找并替换
db.users.findOneAndReplace(
{ name: "John" },
{ name: "John Doe", age: 30 },
{ returnNewDocument: true }
)
八、更新性能 #
8.1 更新优化 #
javascript
// 使用索引加速更新
db.users.createIndex({ name: 1 })
db.users.updateOne({ name: "John" }, { $set: { age: 26 } })
// 批量更新
db.users.updateMany({ status: "inactive" }, { $set: { status: "active" } })
8.2 更新选项 #
javascript
// 更新选项
db.users.updateOne(
{ name: "John" },
{ $set: { age: 26 } },
{
writeConcern: { w: "majority", j: true },
bypassDocumentValidation: false
}
)
九、最佳实践 #
9.1 使用合适的操作符 #
javascript
// 推荐:使用$set只更新需要的字段
db.users.updateOne(
{ name: "John" },
{ $set: { age: 26 } }
)
// 不推荐:使用replaceOne替换整个文档
db.users.replaceOne(
{ name: "John" },
{ name: "John", age: 26 }
)
9.2 使用upsert #
javascript
// 推荐:使用upsert避免重复检查
db.users.updateOne(
{ email: "john@example.com" },
{ $set: { name: "John", age: 26 } },
{ upsert: true }
)
// 不推荐:先查询再插入
const user = db.users.findOne({ email: "john@example.com" })
if (user) {
db.users.updateOne({ email: "john@example.com" }, { $set: { age: 26 } })
} else {
db.users.insertOne({ email: "john@example.com", name: "John", age: 26 })
}
9.3 批量更新 #
javascript
// 推荐:使用updateMany
db.users.updateMany({ status: "inactive" }, { $set: { status: "active" } })
// 不推荐:循环更新
db.users.find({ status: "inactive" }).forEach(user => {
db.users.updateOne({ _id: user._id }, { $set: { status: "active" } })
})
十、总结 #
更新操作速查表:
| 方法 | 说明 | 示例 |
|---|---|---|
| updateOne | 更新单个文档 | db.coll.updateOne({…}, {…}) |
| updateMany | 更新多个文档 | db.coll.updateMany({…}, {…}) |
| replaceOne | 替换文档 | db.coll.replaceOne({…}, {…}) |
常用操作符:
| 操作符 | 说明 |
|---|---|
| $set | 设置字段值 |
| $unset | 删除字段 |
| $inc | 增加数值 |
| $push | 添加数组元素 |
| $pull | 删除数组元素 |
| $addToSet | 添加唯一元素 |
下一步,让我们学习文档删除!
最后更新:2026-03-27