对结果进行排序
Overview
在本指南中,您可以了解如何指定操作结果的顺序。
样本数据
本部分的示例使用以下 Course
结构作为 courses
集合中文档的模型:
type Course struct { Title string Enrollment int32 }
要运行本部分中的示例,请使用以下代码段将样本数据加载到 db.courses
集合中:
coll := client.Database("db").Collection("courses") docs := []interface{}{ Course{Title: "World Fiction", Enrollment: 35}, Course{Title: "Abstract Algebra", Enrollment: 60}, Course{Title: "Modern Poetry", Enrollment: 12}, Course{Title: "Plate Tectonics", Enrollment: 35}, } result, err := coll.InsertMany(context.TODO(), docs)
提示
不存在的数据库和集合
如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。
每个文档均包含某一大学课程的说明,其中包括课程标题和最大注册人数,而它们分别对应于每个文档中的 title
和enrollment
字段。
排序方向
要指定结果的顺序,请将指定排序字段和方向的接口传递给操作选项的 SetSort()
方法。
以下操作将选项作为参数:
Find()
FindOne()
FindOneAndDelete()
FindOneAndUpdate()
FindOneAndReplace()
gridfs.Bucket.Find()
您可以设定升序或降序排序。
升序
升序排序可将结果按从小到大的顺序排序。要指定此排序,请将要作为排序依据的字段和 1
传递给 SetSort()
方法。
提示
通过升序排序,该方法对 Boolean
类型的值按从 false
到 true
的顺序排序,对 String
类型的值按从 a 到 z 的顺序排序,对数值类型的值按从负无穷大到正无穷大的顺序排序。
例子
以下示例将对 enrollment
字段指定升序排序:
filter := bson.D{} opts := options.Find().SetSort(bson.D{{"enrollment", 1}}) cursor, err := coll.Find(context.TODO(), filter, opts) var results []Course if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"title":"Modern Poetry","enrollment":12} {"title":"World Fiction","enrollment":35} {"title":"Plate Tectonics","enrollment":35} {"title":"Abstract Algebra","enrollment":60}
降序
降序排序可将结果按从大到小的顺序排序。要指定此排序,请将要作为排序依据的字段和 -1
传递给 SetSort()
方法。
提示
通过降序排序,此方法会将 Boolean
类型的值从 true
到 false
进行排序,将 String
类型的值从 z 到 a 进行排序,并将数值类型的值从正无穷大到负无穷大进行排序。
例子
以下示例指定对 enrollment
字段进行降序排序:
filter := bson.D{} opts := options.Find().SetSort(bson.D{{"enrollment", -1}}) cursor, err := coll.Find(context.TODO(), filter, opts) var results []Course if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"title":"Abstract Algebra","enrollment":60} {"title":"World Fiction","enrollment":35} {"title":"Plate Tectonics","enrollment":35} {"title":"Modern Poetry","enrollment":12}
处理秩
当两个或更多文档的用来对结果进行排序的字段具有相同的值时,就会出现“并列”情况。如果出现“并列”,MongoDB 不保证顺序。
例如,在样本数据中,以下文档中存在与 enrollment
相关的关系:
{"title":"World Fiction","enrollment":35} {"title":"Plate Tectonics","enrollment":35}
您可以使用附加字段进行排序,以解决原始排序中的“并列”问题。如果要保证文档的特定顺序,请选择不会导致“并列”的排序字段。
例子
以下示例指定对 enrollment
字段进行降序排序,然后对 title
字段进行升序排序:
filter := bson.D{} opts := options.Find().SetSort(bson.D{{"enrollment", -1}, {"title", 1}}) cursor, err := coll.Find(context.TODO(), filter, opts) var results []Course if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"title":"Abstract Algebra","enrollment":60} {"title":"Plate Tectonics","enrollment":35} {"title":"World Fiction","enrollment":35} {"title":"Modern Poetry","enrollment":12}
聚合(Aggregation)
您还可以包含 $sort 阶段,以在聚合管道中指定一个排序。
例子
以下示例指定对 enrollment
字段进行降序排序,然后对 title
字段进行升序排序:
sortStage := bson.D{{"$sort", bson.D{{"enrollment", -1}, {"title", 1}}}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{sortStage}) if err != nil { panic(err) } var results []Course if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"title":"Abstract Algebra","enrollment":60} {"title":"Plate Tectonics","enrollment":35} {"title":"World Fiction","enrollment":35} {"title":"Modern Poetry","enrollment":12}
更多信息
要了解有关提到的操作的更多信息,请参阅以下指南:
要了解如何对文本搜索中的文本得分进行排序,请参阅搜索文本。
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: