Docs 菜单
Docs 主页
/ / /
Go
/ / /

从游标访问数据

在此页面上

  • Overview
  • 示例游标
  • 分别检索文档
  • 可追加游标
  • 检索所有文档
  • 关闭游标
  • 更多信息
  • API 文档

在本指南中,可以了解如何使用游标访问数据。

游标是一种机制,允许应用程序遍历数据库结果,同时在给定时间内只在内存中保留其中的一个子集。匹配多个文档的读取操作会使用游标分批返回这些文档,而不是一次性返回所有文档。

每个部分都使用以下 cursor 变量,它是一个包含集合中所有文档的 Cursor 结构体:

cursor, err := coll.Find(context.TODO(), bson.D{})
if err != nil {
panic(err)
}

在本指南的示例中,驱动程序将 cursor 变量中保存的文档解码到示例 MyStruct 结构。

重要

游标并不具备 goroutine 安全性。请勿在多个 goroutine 中同时使用同一游标。

要在阻止当前 goroutine 的同时从游标单独检索文档,请使用 Next() 方法。

如果满足所有以下条件,该方法返回一个文档:

  • 当前已提供或稍后会提供文档。

  • 驱动程序没有报告任何错误。

  • 上下文未过期。

for cursor.Next(context.TODO()) {
var result MyStruct
if err := cursor.Decode(&result); err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)
}
if err := cursor.Err(); err != nil {
log.Fatal(err)
}

要尝试从可追加游标检索文档,请使用 TryNext() 方法。

如果满足所有以下条件,该方法返回一个文档:

  • 当前有文档可供使用。

  • 驱动程序没有报告任何错误。

  • 上下文未过期。

for {
if cursor.TryNext(context.TODO()) {
var result MyStruct
if err := cursor.Decode(&result); err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)
continue
}
if err := cursor.Err(); err != nil {
log.Fatal(err)
}
if cursor.ID() == 0 {
break
}
}

要将所有查询结果填充到数组中,请使用 All() 方法:

var results []MyStruct
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
fmt.Printf("%+v\n", result)
}

重要

内存

如果查询返回的文档数量和大小超过可用应用程序内存,程序就会崩溃。如果已排除大型结果集,则应以迭代方式使用游标。

当应用程序不再需要使用游标时,请使用Close()方法关闭游标。 此方法可释放游标在客户端应用程序和MongoDB服务器中消耗的资源。

defer cursor.Close(context.TODO())

注意

单独检索文档时关闭游标,因为这些方法会使游标变得可追踪。

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

  • Retrieve Data

  • 指定查询

  • 使用 BSON

  • 可追加游标

如需进一步了解游标以及如何访问游标元素,请参阅以下 API 文档:

后退

Retrieve Data