
本文详解如何将 MongoDB 原生聚合查询(含 $match、$project 中嵌套 $cond 与 $or)准确转换为 Go 语言中基于 mgo 驱动的可执行代码,并提供结构清晰、可直接运行的示例。
本文详解如何将 mongodb 原生聚合查询(含 `$match`、`$project` 中嵌套 `$cond` 与 `$or`)准确转换为 go 语言中基于 mgo 驱动的可执行代码,并提供结构清晰、可直接运行的示例。
在 Go 中使用 mgo 驱动执行 MongoDB 聚合操作,关键在于将每个聚合阶段(stage)正确构造成 bson.M 类型的映射,并按顺序传入 Pipe() 方法。尤其当涉及条件表达式(如 $cond)时,其语法需严格遵循 BSON 数组结构:[$condition, $ifTrue, $ifFalse]。
以下为对应原生 MongoDB 查询的完整 Go 实现:
collection := session.DB("dbName").C("devices")
stageMatch := bson.M{
"$match": bson.M{
"userId": "v73TuQqZykbxFXsWo",
"state": true,
},
}
// 构造 $cond 表达式:若 categorySlug 为 "air_fryer" 或 "iron",weight = 0;否则为 1
conditionWeight := []interface{}{
bson.M{
"$or": []bson.M{
{"$eq": []string{"$categorySlug", "air_fryer"}},
{"$eq": []string{"$categorySlug", "iron"}},
},
},
0, // true 分支
1, // false 分支
}
stageProject := bson.M{
"$project": bson.M{
"userId": 1,
"categorySlug": 1,
"weight": conditionWeight,
},
}
stageSort := bson.M{"$sort": bson.M{"weight": 1}}
stageLimit := bson.M{"$limit": 10}
pipe := collection.Pipe([]bson.M{stageMatch, stageProject, stageSort, stageLimit})
执行聚合后,可通过 All() 或 Iter() 获取结果:
var results []bson.M
err := pipe.All(&results)
if err != nil {
log.Fatal(err)
}
// 处理 results...
⚠️ 注意事项:
-
mgo已归档(官方已标记为 unmaintained),生产环境强烈建议迁移到官方 MongoDB Go Driver(go.mongodb.org/mongo-driver/mongo); -
$cond的三元结构必须是[]interface{}切片,且子条件(如$or)需用bson.M显式声明,不可混用 map[string]interface{} 与切片; - 字段路径字符串(如
"$categorySlug")必须以$开头,否则会被视为字面量而非字段引用; - 所有聚合阶段顺序必须与 MongoDB 原生执行逻辑一致,否则可能导致结果异常或报错。
该写法完全兼容 mgo.v2,结构清晰、语义明确,适合快速集成到现有 Go 项目中。如需进一步扩展(如添加 $group 或 $lookup),只需按相同模式追加对应 bson.M 阶段即可。











