gomog/manual/UPDATE_OPERATORS.md

675 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Gomog 更新操作符参考文档
**版本**: v1.0.0-alpha
**最后更新**: 2026-03-14
---
## 📖 目录
1. [字段更新操作符](#字段更新操作符)
2. [数组更新操作符](#数组更新操作符)
3. [算术更新操作符](#算术更新操作符)
4. [位运算更新操作符](#位运算更新操作符)
5. [条件更新操作符](#条件更新操作符)
6. [使用示例](#使用示例)
---
## 字段更新操作符
### $set - 设置字段
设置字段的值。如果字段不存在,则创建该字段。
**语法**:
```json
{"$set": {"<field>": <value>}}
```
**示例**:
```json
// 设置单个字段
{"$set": {"status": "active"}}
// 设置多个字段
{
"$set": {
"status": "active",
"lastModified": ISODate("2024-01-01")
}
}
// 设置嵌套字段
{"$set": {"address.city": "Beijing"}}
```
### $unset - 移除字段
移除一个或多个字段。
**语法**:
```json
{"$unset": {"<field>": ""}}
// 或
{"$unset": {"<field1>": "", "<field2>": ""}}
```
**示例**:
```json
// 移除单个字段
{"$unset": {"tempField": ""}}
// 移除多个字段
{
"$unset": {
"oldField": "",
"deprecated": ""
}
}
```
### $setOnInsert - 仅在插入时设置
仅在 upsert 操作创建新文档时设置字段。
**语法**:
```json
{"$setOnInsert": {"<field>": <value>}}
```
**示例**:
```json
{
"$setOnInsert": {
"createdAt": ISODate("2024-01-01"),
"createdBy": "system"
}
}
```
### $rename - 重命名字段
重命名字段名。
**语法**:
```json
{"$rename": {"<oldField>": "<newField>"}}
```
**示例**:
```json
// 重命名单个字段
{"$rename": {"oldName": "newName"}}
// 重命名多个字段
{
"$rename": {
"firstName": "givenName",
"lastName": "familyName"
}
}
```
### $currentDate - 设置为当前时间
将字段设置为当前日期或时间戳。
**语法**:
```json
{"$currentDate": {"<field>": <type>}}
```
**类型**:
- `true`: BSON Date (默认)
- `{$type: "timestamp"}`: BSON Timestamp
**示例**:
```json
// 设置为 Date
{"$currentDate": {"lastModified": true}}
// 设置为 Timestamp
{"$currentDate": {"lastModified": {$type: "timestamp"}}}
```
---
## 数组更新操作符
### $push - 推入元素
向数组中添加一个元素。
**语法**:
```json
{"$push": {"<arrayField>": <value>}}
```
**示例**:
```json
// 添加单个元素
{"$push": {"tags": "mongodb"}}
// 添加对象到数组
{"$push": {"scores": {"value": 95, "date": ISODate("2024-01-01")}}}
// 配合 $each 使用
{
"$push": {
"tags": {
"$each": ["database", "nosql"],
"$sort": 1,
"$slice": 10
}
}
}
```
**修饰符**:
- `$each`: 添加多个值
- `$sort`: 排序数组
- `$slice`: 限制数组大小
- `$position`: 指定插入位置
### $addToSet - 添加到集合
向数组中添加元素(如果不存在)。
**语法**:
```json
{"$addToSet": {"<arrayField>": <value>}}
```
**示例**:
```json
// 添加唯一值
{"$addToSet": {"tags": "database"}}
// 配合 $each 使用
{
"$addToSet": {
"tags": {
"$each": ["mongodb", "nosql", "database"]
}
}
}
```
### $pop - 弹出元素
从数组中移除第一个或最后一个元素。
**语法**:
```json
{"$pop": {"<arrayField>": <direction>}}
```
**方向**:
- `1`: 移除最后一个元素
- `-1`: 移除第一个元素
**示例**:
```json
// 移除最后一个元素
{"$pop": {"items": 1}}
// 移除第一个元素
{"$pop": {"items": -1}}
```
### $pull - 拉出元素
从数组中移除所有匹配的元素。
**语法**:
```json
{"$pull": {"<arrayField>": {<query>}}}
```
**示例**:
```json
// 移除等于特定值的元素
{"$pull": {"tags": "deprecated"}}
// 移除满足条件的元素
{"$pull": {
"items": {
"price": {"$lt": 100}
}
}}
// 移除数组中的对象
{"$pull": {
"users": {
"status": "inactive"
}
}}
```
### $pullAll - 拉出多个元素
从数组中移除多个指定的元素。
**语法**:
```json
{"$pullAll": {"<arrayField>": [<value1>, <value2>, ...]}}
```
**示例**:
```json
{"$pullAll": {"tags": ["deprecated", "obsolete", "old"]}}
```
### $splice - 拼接数组
修改数组内容(类似 JavaScript 的 splice
**语法**:
```json
{"$splice": {"<arrayField>": [[start, deleteCount, ...items]]}}
```
**示例**:
```json
// 从索引 2 开始删除 1 个元素,插入 2 个新元素
{"$splice": {"items": [[2, 1, "new1", "new2"]]}}
```
---
## 算术更新操作符
### $inc - 递增
将字段的值增加指定的数量。
**语法**:
```json
{"$inc": {"<field>": <number>}}
```
**示例**:
```json
// 增加计数
{"$inc": {"viewCount": 1}}
// 减少数值
{"$inc": {"stock": -5}}
// 增加浮点数
{"$inc": {"balance": 100.50}}
```
### $mul - 乘法
将字段的值乘以指定的数量。
**语法**:
```json
{"$mul": {"<field>": <number>}}
```
**示例**:
```json
// 打 9 折
{"$mul": {"price": 0.9}}
// 增加 10%
{"$mul": {"quantity": 1.1}}
```
### $min - 最小值
只有当指定值小于当前值时才更新字段。
**语法**:
```json
{"$min": {"<field>": <value>}}
```
**示例**:
```json
// 更新最低价格
{"$min": {"lowPrice": 50}}
```
### $max - 最大值
只有当指定值大于当前值时才更新字段。
**语法**:
```json
{"$max": {"<field>": <value>}}
```
**示例**:
```json
// 更新最高分数
{"$max": {"highScore": 95}}
```
---
## 位运算更新操作符
### $bit - 位运算
对整数字段执行位运算。
**语法**:
```json
{"$bit": {"<field>": {<operation>: <value>}}}
```
**支持的运算**:
- `and`: 按位与
- `or`: 按位或
- `xor`: 按位异或
**示例**:
```json
// 按位与
{"$bit": {"flags": {"and": 15}}} // 保留低 4 位
// 按位或
{"$bit": {"permissions": {"or": 8}}} // 设置第 4 位
// 按位异或
{"$bit": {"status": {"xor": 1}}} // 切换第 1 位
```
---
## 条件更新操作符
### $ - 数组过滤器
更新数组中匹配的第一个元素。
**语法**:
```json
{"<arrayField>.<index>": <value>}
```
**示例**:
```json
// 更新数组第一个元素
{"$set": {"scores.0": 100}}
// 使用 $[identifier] 更新匹配的元素
{
"$set": {
"students.$[elem].grade": "A"
}
},
{
"arrayFilters": [
{"elem.name": "Alice"}
]
}
```
### $[] - 更新所有数组元素
更新数组中的所有元素。
**语法**:
```json
{"<arrayField>.$[]": <value>}
```
**示例**:
```json
// 更新所有数组元素
{"$set": {"scores.$[]": 0}}
```
### $[<identifier>] - 带过滤的数组更新
更新数组中匹配条件的元素。
**语法**:
```json
{"<arrayField>.$[<identifier>]": <value>}
```
**示例**:
```json
{
"$set": {
"students.$[s].grade": "A"
}
},
{
"arrayFilters": [
{"s.score": {"$gte": 90}}
]
}
```
---
## 使用示例
### 用户资料更新
```json
{
"$set": {
"name": "张三",
"email": "zhangsan@example.com"
},
"$inc": {
"loginCount": 1
},
"$currentDate": {
"lastLogin": true
}
}
```
### 购物车操作
```json
{
"$push": {
"items": {
"productId": "prod_001",
"quantity": 2,
"price": 99.99
}
},
"$inc": {
"totalAmount": 199.98
},
"$set": {
"updatedAt": ISODate("2024-01-01")
}
}
```
### 库存管理
```json
{
"$inc": {
"stock": -5,
"soldCount": 5
},
"$min": {
"lowStockAlert": 10
},
"$set": {
"lastSale": ISODate("2024-01-01")
}
}
```
### 评分系统
```json
{
"$push": {
"ratings": {
"userId": "user_001",
"score": 5,
"comment": "Excellent!"
}
},
"$inc": {
"ratingCount": 1,
"totalScore": 5
},
"$set": {
"averageRating": {"$divide": ["$totalScore", "$ratingCount"]}
}
}
```
### 标签管理
```json
{
"$addToSet": {
"tags": "new"
},
"$pull": {
"tags": "old"
},
"$push": {
"history": {
"$each": ["tag_updated"],
"$slice": -10
}
}
}
```
### 批量更新
```json
// 更新多个文档
{
"filter": {"department": "技术部"},
"update": {
"$inc": {"salary": 1000},
"$set": {"adjusted": true}
},
"multi": true
}
```
### Upsert 操作
```json
{
"filter": {"email": "user@example.com"},
"update": {
"$setOnInsert": {
"email": "user@example.com",
"createdAt": ISODate("2024-01-01")
},
"$set": {
"lastSeen": ISODate("2024-01-01")
},
"$inc": {
"visitCount": 1
}
},
"upsert": true
}
```
### 复杂数组操作
```json
{
"$push": {
"scores": {
"$each": [95, 87, 92],
"$sort": -1,
"$slice": 5,
"$position": 0
}
}
}
```
### 嵌套字段更新
```json
{
"$set": {
"address.street": "长安街",
"address.city": "北京",
"contact.phone": "123456789"
},
"$unset": {
"address.oldAddress": ""
}
}
```
---
## 最佳实践
### 1. 原子性保证
Gomog 的更新操作是原子的,可以安全地并发使用。
```json
// 安全的计数器递增
{"$inc": {"viewCount": 1}}
```
### 2. 使用 $setOnInsert 避免覆盖
```json
// ✅ 推荐:只在插入时设置创建时间
{
"$setOnInsert": {"createdAt": ISODate()},
"$set": {"updatedAt": ISODate()}
}
```
### 3. 合理使用数组修饰符
```json
// 限制数组大小,防止无限增长
{
"$push": {
"history": {
"$each": [newItem],
"$slice": -100 // 只保留最后 100 条
}
}
}
```
### 4. 使用 arrayFilters 精确更新
```json
// 精确定位要更新的数组元素
{
"$set": {"grades.$[g].grade": "A"},
"arrayFilters": [{"g.subject": "math"}]
}
```
### 5. 避免频繁更新大文档
```json
// ❌ 不推荐:每次更新整个文档
{"$set": {entireDocument}}
// ✅ 推荐:只更新变化的字段
{"$set": {"changedField": newValue}}
```
---
**维护者**: Gomog Team
**许可证**: MIT