feat(engine): 实现聚合表达式增强和查询操作符扩展
- 添加算术操作符:$abs, $ceil, $floor, $round, $sqrt, $subtract, $pow - 添加字符串操作符:$trim, $ltrim, $rtrim, $split, $replaceAll, $strcasecmp - 添加布尔操作符:$and, $or, $not 聚合版本 - 添加集合操作符:$filter, $map, $slice, $concatArrays - 添加对象操作符:$mergeObjects, $objectToArray - 添加日期操作符:$year, $month, $dayOfMonth, $hour, $minute, $second等 - 实现$expr聚合表达式查询功能 - 实现$jsonSchema文档验证支持 - 添加投影操作符:$elemMatch, $slice - 实现更新操作符:$setOnInsert, 数组位置操作符和arrayFilters - 更新IMPLEMENTATION_PROGRESS.md记录完成状态 - 增加Batch 2测试脚本和API测试示例
This commit is contained in:
parent
76b86b4b43
commit
83f3c57939
|
|
@ -123,33 +123,258 @@
|
|||
|
||||
---
|
||||
|
||||
#### 4. 聚合表达式增强(已完成)
|
||||
|
||||
**已实现:**
|
||||
- ✅ 算术操作符:`$abs`, `$ceil`, `$floor`, `$round`, `$sqrt`, `$subtract`, `$pow`
|
||||
- ✅ 字符串操作符:`$trim`, `$ltrim`, `$rtrim`, `$split`, `$replaceAll`, `$strcasecmp`
|
||||
- ✅ 布尔操作符:`$and`, `$or`, `$not` (聚合版本)
|
||||
- ✅ 集合操作符:`$filter`, `$map`, `$slice`, `$concatArrays`
|
||||
- ✅ 对象操作符:`$mergeObjects`, `$objectToArray`
|
||||
- ✅ 日期操作符:`$year`, `$month`, `$dayOfMonth`, `$hour`, `$minute`, `$second`, `$dateToString`, `$now`, `$dateAdd`, `$dateDiff`
|
||||
- ✅ 条件表达式:`$cond`, `$ifNull`, `$switch`
|
||||
- ✅ 比较操作符:`$gt`, `$gte`, `$lt`, `$lte`, `$eq`, `$ne`
|
||||
|
||||
**实现文件:**
|
||||
- `internal/engine/aggregate.go` - 添加了各种表达式处理方法和 compareXxx 系列函数
|
||||
- `internal/engine/aggregate_helpers.go` - 添加了 switchExpr 等辅助函数
|
||||
|
||||
**使用示例:**
|
||||
```json
|
||||
// $abs - 绝对值
|
||||
{"pipeline": [{"$addFields": {"absValue": {"$abs": "$value"}}}]}
|
||||
|
||||
// $ceil - 向上取整
|
||||
{"pipeline": [{"$addFields": {"ceiled": {"$ceil": "$price"}}}]}
|
||||
|
||||
// $cond - 条件表达式
|
||||
{"pipeline": [{"$addFields": {
|
||||
"discount": {"$cond": [
|
||||
{"$gte": ["$amount", 100]},
|
||||
{"$multiply": ["$price", 0.9]},
|
||||
"$price"
|
||||
]}
|
||||
}}]}
|
||||
|
||||
// $switch - 多分支条件
|
||||
{
|
||||
"pipeline": [{
|
||||
"$addFields": {
|
||||
"grade": {
|
||||
"$switch": {
|
||||
"branches": [
|
||||
{"case": {"$gte": ["$score", 90]}, "then": "A"},
|
||||
{"case": {"$gte": ["$score", 80]}, "then": "B"}
|
||||
],
|
||||
"default": "C"
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
// $filter - 过滤数组
|
||||
{"pipeline": [{"$addFields": {
|
||||
"highScores": {"$filter": {
|
||||
"input": "$scores",
|
||||
"as": "score",
|
||||
"cond": {"$gte": ["$$score", 90]}
|
||||
}}
|
||||
}}]}
|
||||
|
||||
// $dateToString - 日期格式化
|
||||
{"pipeline": [{"$addFields": {
|
||||
"dateStr": {"$dateToString": {"format": "%Y-%m-%d", "date": "$createdAt"}}
|
||||
}}]}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 5. 查询操作符增强(第二批)
|
||||
|
||||
**已实现:**
|
||||
- ✅ `$expr` - 聚合表达式查询:`{"$expr": {"$gt": ["$qty", "$minQty"]}}`
|
||||
- ✅ `$jsonSchema` - JSON Schema 验证
|
||||
|
||||
**实现文件:**
|
||||
- `internal/engine/query.go` - 添加了 handleExpr() 和 handleJSONSchema() 函数
|
||||
- `internal/engine/query.go` - 添加了 validateFieldValue() 和完整的 JSON Schema 验证逻辑
|
||||
|
||||
**支持的模式验证关键字:**
|
||||
- `bsonType` - BSON 类型检查
|
||||
- `required` - 必需字段
|
||||
- `properties` - 属性定义
|
||||
- `enum` - 枚举值
|
||||
- `minimum` / `maximum` - 数值范围
|
||||
- `minLength` / `maxLength` - 字符串长度
|
||||
- `pattern` - 正则表达式
|
||||
- `items` - 数组元素 schema
|
||||
- `minItems` / `maxItems` - 数组长度
|
||||
- `allOf` / `anyOf` / `oneOf` / `not` - 组合验证
|
||||
|
||||
**使用示例:**
|
||||
```json
|
||||
// $expr - 字段间比较
|
||||
{"filter": {"$expr": {"$gt": ["$qty", "$minQty"]}}}
|
||||
|
||||
// $expr - 复杂计算
|
||||
{"filter": {"$expr": {"$lte": [
|
||||
{"$add": ["$price", "$tax"]},
|
||||
100
|
||||
]}}}
|
||||
|
||||
// $jsonSchema - 完整文档验证
|
||||
{"filter": {"$jsonSchema": {
|
||||
"bsonType": "object",
|
||||
"required": ["name", "age"],
|
||||
"properties": {
|
||||
"name": {"bsonType": "string", "minLength": 1},
|
||||
"age": {"bsonType": "int", "minimum": 0, "maximum": 150}
|
||||
}
|
||||
}}}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 6. 投影操作符(已完成)
|
||||
|
||||
**已实现:**
|
||||
- ✅ `$elemMatch` - 投影数组中第一个匹配的元素
|
||||
- ✅ `$slice` - 切片操作(支持 skip/limit 语法)
|
||||
|
||||
**实现文件:**
|
||||
- `internal/engine/projection.go` - 新增文件,包含 applyProjection() 和相关函数
|
||||
- `internal/engine/crud_handler.go` - 在 Find() 方法中集成投影功能
|
||||
|
||||
**使用示例:**
|
||||
```json
|
||||
// $elemMatch - 投影数组中第一个匹配的元素
|
||||
{
|
||||
"projection": {
|
||||
"grades": {"$elemMatch": {"$gte": 90}}
|
||||
}
|
||||
}
|
||||
|
||||
// $slice - 前 5 个元素
|
||||
{
|
||||
"projection": {
|
||||
"comments": {"$slice": 5}
|
||||
}
|
||||
}
|
||||
|
||||
// $slice - 跳过前 10 个,取 5 个
|
||||
{
|
||||
"projection": {
|
||||
"comments": {"$slice": [10, 5]}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 7. 更新操作符增强(第二批)
|
||||
|
||||
**已实现:**
|
||||
- ✅ `$setOnInsert` - 仅在 upsert 插入时设置字段
|
||||
- ✅ 数组位置操作符:`$`, `$[]`, `$[identifier]`
|
||||
- ✅ arrayFilters 支持
|
||||
|
||||
**实现文件:**
|
||||
- `pkg/types/document.go` - 在 Update 结构体中添加 SetOnInsert 字段
|
||||
- `pkg/types/document.go` - 在 UpdateOperation 中添加 ArrayFilters 字段
|
||||
- `internal/engine/crud.go` - 在 applyUpdateWithFilters() 中添加 $setOnInsert 处理
|
||||
- `internal/engine/crud.go` - 实现了 updateArrayElement() 和 updateArrayAtPath() 函数
|
||||
- `internal/engine/memory_store.go` - 更新了 Update() 方法签名支持 upsert 和 arrayFilters
|
||||
|
||||
**使用示例:**
|
||||
```json
|
||||
// $setOnInsert - upsert 时设置创建时间
|
||||
{
|
||||
"update": {
|
||||
"$set": {"status": "active"},
|
||||
"$setOnInsert": {"createdAt": "2024-01-01T00:00:00Z"}
|
||||
},
|
||||
"upsert": true
|
||||
}
|
||||
|
||||
// $[] - 更新数组所有元素
|
||||
{
|
||||
"update": {
|
||||
"$set": {"scores.$[]": 100}
|
||||
}
|
||||
}
|
||||
|
||||
// $[identifier] - 条件更新数组元素
|
||||
{
|
||||
"update": {
|
||||
"$set": {"students.$[elem].grade": "A"}
|
||||
},
|
||||
"arrayFilters": [
|
||||
{"identifier": "elem", "score": {"$gte": 90}}
|
||||
]
|
||||
}
|
||||
|
||||
// $ - 更新第一个元素(简化实现)
|
||||
{
|
||||
"update": {
|
||||
"$set": {"items.$.status": "updated"}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 待实现的功能
|
||||
|
||||
### ⏳ 聚合表达式增强(未开始)
|
||||
### ⏳ 第三批功能(计划中)
|
||||
|
||||
**计划实现:**
|
||||
- 算术:`$abs`, `$ceil`, `$floor`, `$round`, `$sqrt`, `$subtract`, `$pow`
|
||||
- 字符串:`$trim`, `$ltrim`, `$rtrim`, `$split`, `$replaceAll`, `$strcasecmp`
|
||||
- 布尔:`$and`, `$or`, `$not` (聚合版本)
|
||||
- 集合:`$filter`, `$map`, `$slice`, `$concatArrays`
|
||||
- 对象:`$mergeObjects`, `$objectToArray`
|
||||
- 日期:`$year`, `$month`, `$dayOfMonth`, `$hour`, `$minute`, `$second`, `$dateToString`, `$now`
|
||||
**高级聚合阶段:**
|
||||
- `$setWindowFields` - 窗口函数
|
||||
- `$graphLookup` - 递归查找
|
||||
- `$replaceRoot` / `$replaceWith` - 替换根文档
|
||||
- `$unionWith` - 与其他集合并集
|
||||
- `$redact` - 文档级访问控制
|
||||
- `$text` - 文本搜索
|
||||
|
||||
### ⏳ Date 类型完整支持(未开始)
|
||||
**更多日期操作符:**
|
||||
- `$week` - 一年中的第几周
|
||||
- `$isoWeek` - ISO 周数
|
||||
- `$dayOfYear` - 一年中的第几天
|
||||
- `$isoDayOfWeek` - ISO 星期几
|
||||
|
||||
**位运算操作符(聚合版本):**
|
||||
- `$bitAnd`, `$bitOr`, `$bitXor`, `$bitNot`
|
||||
|
||||
**类型转换操作符:**
|
||||
- `$toString`, `$toInt`, `$toLong`, `$toDouble`, `$toBool`, `$toDate`, `$toObjectId`
|
||||
|
||||
### ⏳ Date 类型完整支持(部分完成)
|
||||
|
||||
**已完成:**
|
||||
- ✅ 日期操作符:`$year`, `$month`, `$dayOfMonth`, `$hour`, `$minute`, `$second`
|
||||
- ✅ 日期格式化:`$dateToString`
|
||||
- ✅ 日期计算:`$dateAdd`, `$dateDiff`
|
||||
- ✅ 当前时间:`$now`
|
||||
|
||||
**需要实现:**
|
||||
- BSON Date 类型解析和序列化
|
||||
- 时区支持
|
||||
- 日期格式化函数
|
||||
- 日期计算函数
|
||||
- BSON Date 类型解析和序列化优化
|
||||
- 时区支持(timezone 参数)
|
||||
- 更复杂的日期计算函数
|
||||
|
||||
### ⏳ 测试和文档(未开始)
|
||||
### ⏳ 测试和文档(部分完成)
|
||||
|
||||
**已完成:**
|
||||
- ✅ Batch 2 功能的单元测试(query_batch2_test.go, crud_batch2_test.go 等)
|
||||
- ✅ 集成测试(integration_batch2_test.go)
|
||||
- ✅ HTTP API 测试(http/batch2_test.go)
|
||||
- ✅ 测试文档(TEST_DOCUMENTATION.md)
|
||||
|
||||
**需要完成:**
|
||||
- 单元测试
|
||||
- 集成测试
|
||||
- API 文档
|
||||
- 使用示例
|
||||
- 性能基准测试
|
||||
- Fuzz 测试
|
||||
- 并发安全测试
|
||||
- 完整的 API 文档
|
||||
- 用户使用指南
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -157,14 +382,19 @@
|
|||
|
||||
### 已完成的改进:
|
||||
1. ✅ 统一了错误处理模式
|
||||
2. ✅ 添加了辅助函数(toInt64, toFloat64 等)
|
||||
2. ✅ 添加了辅助函数(toInt64, toFloat64, toNumber 等)
|
||||
3. ✅ 实现了随机种子初始化
|
||||
4. ✅ 代码注释完善
|
||||
5. ✅ 添加了字段引用处理($ 前缀)
|
||||
6. ✅ 完善了比较操作符支持
|
||||
7. ✅ 实现了复杂的 JSON Schema 验证
|
||||
8. ✅ 添加了数组位置操作符完整支持
|
||||
|
||||
### 建议的改进:
|
||||
1. 添加更多边界情况处理
|
||||
2. 性能优化(如添加索引支持)
|
||||
3. 添加基准测试
|
||||
4. 内存使用优化
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -172,25 +402,27 @@
|
|||
|
||||
| 类别 | 已实现 | 总计 | 完成率 |
|
||||
|------|--------|------|--------|
|
||||
| 查询操作符 | 13 | 18 | 72% |
|
||||
| 更新操作符 | 13 | 20 | 65% |
|
||||
| 查询操作符 | 15 | 18 | 83% |
|
||||
| 更新操作符 | 17 | 20 | 85% |
|
||||
| 聚合阶段 | 14 | 25 | 56% |
|
||||
| 聚合表达式 | ~15 | ~70 | 21% |
|
||||
| **总体** | **~55** | **~133** | **~41%** |
|
||||
| 聚合表达式 | ~45 | ~70 | 64% |
|
||||
| **总体** | **~91** | **~133** | **~68%** |
|
||||
|
||||
---
|
||||
|
||||
## 下一步计划
|
||||
|
||||
### 立即执行:
|
||||
1. 实现聚合表达式增强(算术、字符串、集合操作符)
|
||||
2. 实现完整的 Date 类型支持
|
||||
3. 编写单元测试
|
||||
### 立即执行(Batch 3):
|
||||
1. 实现窗口函数 `$setWindowFields`
|
||||
2. 实现递归查找 `$graphLookup`
|
||||
3. 实现文档替换 `$replaceRoot` / `$replaceWith`
|
||||
4. 实现文本搜索 `$text`
|
||||
|
||||
### 后续批次:
|
||||
1. 实现 `$expr` 聚合表达式查询
|
||||
2. 实现投影操作符(`$elemMatch`, `$slice`)
|
||||
3. 实现窗口函数和其他高级功能
|
||||
1. 完善 Date 类型的时区支持
|
||||
2. 实现类型转换操作符
|
||||
3. 添加性能基准测试
|
||||
4. 编写完整的 API 文档
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -201,31 +433,52 @@
|
|||
go test ./internal/engine/... -v
|
||||
```
|
||||
|
||||
### 运行所有 Batch 2 测试
|
||||
```bash
|
||||
./test_batch2.sh
|
||||
```
|
||||
|
||||
### API 测试
|
||||
```bash
|
||||
# 测试 $mod
|
||||
# 测试 $expr
|
||||
curl -X POST http://localhost:8080/api/v1/testdb/products/find \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"filter": {"quantity": {"$mod": [5, 0]}}}'
|
||||
-d '{"filter": {"$expr": {"$gt": ["$qty", "$minQty"]}}}'
|
||||
|
||||
# 测试 $facet
|
||||
curl -X POST http://localhost:8080/api/v1/testdb/orders/aggregate \
|
||||
# 测试 $switch
|
||||
curl -X POST http://localhost:8080/api/v1/testdb/students/aggregate \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"pipeline": [{
|
||||
"$facet": {
|
||||
"byStatus": [
|
||||
{"$group": {"_id": "$status", "count": {"$sum": 1}}}
|
||||
],
|
||||
"totalRevenue": [
|
||||
{"$group": {"_id": null, "total": {"$sum": "$amount"}}}
|
||||
]
|
||||
"$addFields": {
|
||||
"grade": {
|
||||
"$switch": {
|
||||
"branches": [
|
||||
{"case": {"$gte": ["$score", 90]}, "then": "A"},
|
||||
{"case": {"$gte": ["$score", 80]}, "then": "B"}
|
||||
],
|
||||
"default": "C"
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}'
|
||||
|
||||
# 测试 $setOnInsert with upsert
|
||||
curl -X POST http://localhost:8080/api/v1/testdb/users/update \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"filter": {"_id": "new_user"},
|
||||
"update": {
|
||||
"$set": {"status": "active"},
|
||||
"$setOnInsert": {"createdAt": "2024-01-01T00:00:00Z"}
|
||||
},
|
||||
"upsert": true
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**报告生成时间**: 2026-03-13
|
||||
**版本**: v1.0.0-alpha
|
||||
**报告生成时间**: 2026-03-14
|
||||
**版本**: v1.0.0-alpha
|
||||
**最新批次**: Batch 2 (已完成)
|
||||
|
|
|
|||
Loading…
Reference in New Issue