Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/ / /
Go 驱动程序
/ /

指定要返回的文档

在本指南中,您可以学习;了解如何使用以下方法指定从读取操作中返回哪些文档:

  • SetSort():指定返回文档的排序顺序。

  • SetSkip():指定在返回查询结果之前要跳过的文档数。

  • SetLimit():指定从查询中返回的最大文档数。

本指南中的示例使用以下 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)

提示

不存在的数据库和集合

如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。

每个文档代表一门大学课程的描述,包括课程标题和最大注册人数,分别对应于每个文档中的 titleenrollment 字段。

要指定结果的顺序,请将指定排序字段和方向的接口传递给操作选项的 SetSort() 方法。

以下操作将 SetSort() 作为选项:

  • Find()

  • FindOne()

  • FindOneAndDelete()

  • FindOneAndUpdate()

  • FindOneAndReplace()

  • GridFSBucket.Find()

您可以设定升序降序排序。

升序排序可将结果按从小到大的顺序排序。要指定此排序,请将要作为排序依据的字段和 1 传递给 SetSort() 方法。

提示

通过升序排序,该方法对 Boolean 类型的值按从 falsetrue 的顺序排序,对 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 类型的值从 truefalse 进行排序,将 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}

您还可以包含 $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}

要跳过查询返回的指定数量的结果,请将要跳过的文档数量传递给读取操作选项的SetSkip()方法。

以下读取操作将 SetSkip() 作为选项:

  • Find()

  • FindOne()

  • CountDocuments()

  • GridFSBucket.Find()

如果文档数量超过查询的匹配文档数量,则该查询不会返回任何文档。

查找操作按存储顺序返回文档,未按任何字段排序。为避免跳过随机文档,请在设置跳过选项之前,使用SetSort()方法按具有唯一值的字段对文档进行排序。

以下示例通过以下行为执行 Find() 操作:

  • enrollment字段中按升序对结果进行排序

  • 跳过前两个文档

opts := options.Find().SetSort(bson.D{{"enrollment", 1}}).SetSkip(2)
cursor, err := coll.Find(context.TODO(), bson.D{}, 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":"Plate Tectonics","enrollment":35}
{"title":"Abstract Algebra","enrollment":60}

您还可以在聚合管道中包含 $skip 阶段,以跳过某些文档。

以下示例通过以下行为执行Aggregate()操作:

  • enrollment(注册)字段中按降序对结果进行排序

  • 跳过第一个文档

sortStage := bson.D{{"$sort", bson.D{{"enrollment", -1}}}}
skipStage := bson.D{{"$skip", 1}}
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{sortStage, skipStage})
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":"Plate Tectonics","enrollment":35}
{"title":"World Fiction","enrollment":35}
{"title":"Modern Poetry","enrollment":12}

要限制查询返回的文档数量,请将您想要返回的文档数量传递给读取操作选项的 SetLimit() 方法。

以下读取操作将 SetLimit() 作为选项:

  • Find()

  • CountDocuments()

  • GridFSBucket.Find()

如果限制为 0 或超过匹配的文档数量,该方法将返回所有文档。如果限制是负数,该方法将负数的绝对值作为限制,并在检索文档后关闭游标。

以下示例展示如何返回enrollment字段值大于 20 的两个文档:

filter := bson.D{{"enrollment", bson.D{{"$gt", 20}}}}
opts := options.Find().SetLimit(2)
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":"World Fiction","enrollment":35}
{"title":"Abstract Algebra","enrollment":60}

无论您设立任何其他选项的顺序如何,驾驶员都会最后执行限制行为。示例,无论调用 SetLimit() 的顺序如何,以下选项配置都会产生相同的结果:

opts := options.Find().SetSort(bson.D{{"enrollment", -1}}).SetSkip(1).SetLimit(2)
opts := options.Find().SetLimit(2).SetSort(bson.D{{"enrollment", -1}}).SetSkip(1)

以下示例通过以下行为执行 Find() 操作:

  • enrollment(注册)字段中按降序对结果进行排序

  • 跳过第一个文档

  • 返回剩余文档中的前两份文档

filter := bson.D{}
opts := options.Find().SetSort(bson.D{{"enrollment", -1}}).SetLimit(2).SetSkip(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}

您还可以包含 $limit 阶段,以在聚合管道中指定一个限制。

以下示例显示如何返回三个文档:

limitStage := bson.D{{"$limit", 3}}
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{limitStage})
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":"World Fiction","enrollment":35}
{"title":"Abstract Algebra","enrollment":60}
{"title":"Modern Poetry","enrollment":12}

要学习;了解有关本指南中讨论的操作的更多信息,请参阅以下文档:

  • 指定查询

  • 查找文档

  • 复合运算符

  • 聚合(Aggregation)

要学习;了解如何对文本搜索中的文本分数进行排序,请参阅执行文本搜索。

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档:

后退

从游标访问数据

在此页面上