675 lines
9.5 KiB
Markdown
675 lines
9.5 KiB
Markdown
# 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
|