本文详解如何将字符串切片(如 []string{"-created_when", "title"})正确展开为 mgo.Sort() 所需的可变参数形式,避免因误用 strings.Join 导致排序失效的问题。
本文详解如何将字符串切片(如 `[]string{"-created_when", "title"}`)正确展开为 mgo.sort() 所需的可变参数形式,避免因误用 `strings.join` 导致排序失效的问题。
在使用旧版 MongoDB 驱动 mgo(labix.org/v2/mgo)进行查询时,Sort() 方法签名如下:
func (q *Query) Sort(fields ...string) *Query
该方法接受可变数量的字符串参数(即 ...string),而非单个逗号分隔的字符串。因此,若直接将切片通过 strings.Join(sortBy, ",") 拼接成 " -created_when,title " 并传入,mgo 会将其视为一个字段名(含连字符和逗号),而非两个独立的排序字段——这正是问题中“查询不工作”的根本原因。
✅ 正确做法是利用 Go 的切片展开语法(spread operator):sortBy...。它会将切片中的每个元素作为独立实参传递给 Sort(),完全等价于手动书写 Sort("-created_when", "title")。
✅ 正确示例代码
import (
"gopkg.in/mgo.v2"
"strings"
)
// 动态排序字段(支持升序/降序)
sortBy := []string{"-created_when", "title"}
// ✅ 正确:使用 ... 展开切片
iter := db.C("articles").Find(bson.M{}).Limit(50).Sort(sortBy...).Iter()⚠️ 注意事项
-
切片不能为空:若 sortBy 为空切片(len(sortBy) == 0),调用 Sort(sortBy...) 将传入零个参数,此时 mgo 默认不排序(行为安全,但需确认是否符合业务预期)。建议显式校验:
if len(sortBy) > 0 { query = query.Sort(sortBy...) } - 字段名需合法:确保切片中每个字符串均为有效 BSON 字段路径(如 "name"、"meta.score"、"-updated_at"),非法字段会导致查询无报错但排序无效。
-
注意 mgo 已归档:mgo 官方已停止维护(自 2018 年起),生产环境强烈推荐迁移至官方驱动 mongo-go-driver。其对应排序写法为:
options.Sort = bson.D{{"created_when", -1}, {"title", 1}}
总结
核心要点仅有一条:Sort() 接收的是多个 string 参数,不是单个逗号分隔字符串;动态场景下必须用 slice... 展开,而非 strings.Join。掌握这一 Go 语言基础特性,即可安全、高效地实现运行时排序策略配置。


















