聚合查询时,语法不正确导致无法查询数据?
在提交之前请先查找 已有 issues,避免重复上报。| Before submitting, please search for existing issues to avoid duplicate reports.
并且确保自己已经 | Also, ensure that you have:
- [x] 阅读过文档 | Read the documentation
- [x] 阅读过注释 | Reviewed the comments
- [x] 阅读过例子 | Looked at the examples
您使用的 mongox 版本 | The version of mongox you are using
您遇到的问题 | The issue you encountered.
我需要类似以下的查询语法
startTime := time.Now()
endTime := startTime.AddHour()
pipeline := []bson.M{
// Match stage
{
"$match": bson.M{
"createdAt": bson.M{
"$gte": startTime,
"$lt": endTime,
},
},
},
// Group stage
{
"$group": bson.M{
"_id": bson.M{
"statAt": bson.M{
"$dateToString": bson.M{
"format": "%Y-%m-%d %H",
"date": "$createdAt",
},
},
"userId": "$userId",
"type": "$type",
},
"statCount": bson.M{
"$sum": 1,
},
"statCredits": bson.M{
"$sum": "$credits",
},
},
},
// Sort stage
{
"$sort": bson.M{
"_id.statAt": -1,
"_id.type": -1,
},
},
}
- 我使用
aggregation相关构造器
stageBuilder := aggregation.NewStageBuilder()
// Match stage
matchBuilder := aggregation.NewBuilder().
Gte("createdAt", in.StartTime).
Lt("createdAt", in.EndTime)
stageBuilder.Match(matchBuilder.Build())
// Group stage
groupIDBuilder := aggregation.NewBuilder().
DateToString("statAt", "$createdAt", &aggregation.DateToStringOptions{
Format: "%Y-%m-%d %H",
// Timezone: "UTC",
}).
KeyValue("userId", "$userId").
KeyValue("type", "$type")
// 添加统计数量的管道阶段
groupFields := aggregation.NewBuilder().
Sum("statCount", 1).
Sum("statCredits", "$credits")
stageBuilder.Group(groupIDBuilder.Build(), groupFields.Build()...)
// Sort stage
stageBuilder.Sort(bson.D{
{"_id.date", -1},
{"_id.type", -1},
})
// 序列化查询语句
stageBuilderBytes, _ := json.Marshal(stageBuilder.Build())
println(string(stageBuilderBytes))
- 我得到了以下语句
[{"$match":{"createdAt":{"$gte":["2025-10-17T03:00:00Z"],"$lt":["2025-10-17T04:00:00Z"]}}},{"$group":{"_id":{"statAt":{"$dateToString":{"date":"$createdAt","format":"%Y-%m-%d %H"}},"userId":"$userId","type":"$type"},"statCount":{"$sum":1},"statCredits":{"$sum":"$credits"}}},{"$sort":{"_id.date":-1,"_id.type":-1}}]
- 它们的差异在于
$match阶段的createdAt条件类型不一致
- 我使用 Mongo SHELL 执行无法查询到数据, 因为
createdAt语法不对
复现步骤 | Steps to reproduce
请提供简单的复现代码 | Please provide simple code to reproduce the issue.
错误日志或者截图 | Error logs or Screenshots
你排查的结果,或者你觉得可行的修复方案 | Your Findings or Possible Solutions
可选。我们希望你能够尽量先排查问题,帮助我们减轻维护负担。这对于你个人能力提升同样是有帮助的。| Optional. We hope you can try to troubleshoot the issue first, helping us to reduce our maintenance burden. This is also beneficial for your personal skill development
您期望的结果 | Expected Outcome
你设置的的 Go 环境 | Your Go Environment Setting
上传
go env的结果 | Upload the result ofgo env
@chenmingyong0423 语法错误导致无法按时间聚合数据
下面这样就行
理解你的疑问,我来解释一下这个问题吧。首先,先说明一下,通过 aggregation.NewBuilder() 获得的构建器,是用于构建聚合表达式的构建器,我们知道,聚合表达式(Aggregation Expressions) 和普通的 查询 / 更新表达式 在 MongoDB 里既有相似之处,也有显著区别。而你这里的:
bson.M{
"createdAt": bson.M{
"$gte": startTime,
"$lt": endTime,
},
}
其实不算 聚合表达式,而是归属于 查询表达式 因此你不能用 aggregation.NewBuilder() 去构建,而是用 queryBuilder := query.NewBuilder().Gte("createdAt", in.StartTime).Lt("createdAt", in.EndTime) 去构建才是对的,所以将 queryBuilder := query.NewBuilder().Gte("createdAt", in.StartTime).Lt("createdAt", in.EndTime) 代替 matchBuilder := aggregation.NewBuilder().Gte("createdAt", in.StartTime).Lt("createdAt", in.EndTime) 就可以得到正确的数据了。看来我需要在某个地方去强调一下这些构建器的区别,用户才能够容易,正确地使用。感谢你的反馈!