Docs 菜单
Docs 主页
/ / /
Rust 驱动程序
/ / /

使用游标访问数据

在此页面上

  • Overview
  • 示例样本数据
  • 分别检索文档
  • 内置模式
  • 流实现模式
  • 以数组形式检索文档
  • 指定游标行为
  • 更多信息
  • API 文档

在本指南中,您可以了解如何使用 Rust 驱动程序通过游标访问读取操作或聚合返回的数据。 游标是一种机制,可让您迭代多个文档,同时在给定时间仅在内存中保存其中的子集。

驱动程序提供 Cursor类型以从游标检索文档。 例如,当您运行可以返回多个文档的查找操作时,驱动程序会返回一个Cursor实例,您可以从该实例访问匹配的文档。

Cursor运行读操作或聚合后,返回的实例包含该操作的批处理结果。当您遍历游标时,服务器会返回更多单独的结果。 如果在到达一批处理结果的末尾后还有更多匹配文档,则Cursor实例将获取下一批处理文档,直到返回所有结果。

本指南包括以下部分:

  • 示例的样本数据显示了游标示例使用的样本数据

  • 单独检索文档描述了如何使用迭代或流一次访问一个结果

  • 以数组形式检索文档描述了如何通过收集返回的游标结果,以单个大量形式访问权限所有结果

  • 指定游标行为描述了如何配置方法返回的游标

  • 附加信息提供了本指南中提到的类型和方法的资源和 API 文档链接

本指南中的示例使用存储在结构体中的以下数据:

let docs = vec! [
Fruit {
name: "strawberry".to_string(),
color: "red".to_string()
},
Fruit {
name: "banana".to_string(),
color: "yellow".to_string()
},
Fruit {
name: "pomegranate".to_string(),
color: "red".to_string()
},
Fruit {
name: "pineapple".to_string(),
color: "yellow".to_string()
}
];

该驱动程序提供以下访问模式来遍历Cursor实例返回的文档:

  • 内置模式:前进游标,然后检索并反序列化当前文档

  • 流实现模式:迭代游标并调用Stream提供的方法来进程单个或多个文档

以下部分将更详细地描述这些访问模式和相应的方法。

您可以使用驱动程序的内置访问模式逐份检索和处理文档。

Cursor类型包括advance()deserialize_current()方法,用于遍历游标并分别访问文档。

advance()方法会向前移动游标,并在本地缓冲区耗尽时(游标到达一批处理结果的末尾时会发生这种情况)向数据库发送请求以获取更多结果。每次游标到达批处理结果的末尾时,它都会请求下一批处理结果。当游标没有更多匹配文档可返回并且不再可用时,游标已耗尽。 如果成功返回新结果,则advance()方法会返回true结果;如果关闭游标,则返回false结果。

deserialize_current()方法返回对游标中当前结果的引用,并将结果反序列化为与游标关联的类型。 除非指定类型,否则该方法将使用对collection进行参数化时使用的同一类型。

重要

仅当advance()方法返回true结果时,才能调用deserialize_current()方法。 如果您在游标上调用deserialize_current()没有true结果,或者没有调用之前调用的advance() ,则驱动程序会生成错误。

以下示例展示了如何实现此访问模式以遍历collection上查找操作的结果:fruits

let mut cursor = my_coll.find(doc! { "color": "red" }).await?;
while cursor.advance().await? {
println!("{:?}", cursor.deserialize_current()?);
}
Fruit { name: "strawberry", color: "red" }
Fruit { name: "pomegranate", color: "red" }

您可以以流的形式访问游标结果,以检索单个文档或一次收集多个文档。

Cursor类型实现了Stream特征,因此您可以将游标作为流进行迭代。 与内置模式相比,此模式可帮助您编写更简洁的代码,因为Stream扩展特征StreamExt提供了许多用于组合操作和整合代码的函数。

您可以通过以下方法来使用流模式:

  • next():将游标前进到下一个结果并返回Option<Result<T>>类型

  • try_next():将游标前进到下一个结果并返回Result<Option<T>>类型

重要

流模式方法所需的导入

要使用next()方法,您必须导入StreamExt特征。 要使用try_next()方法,您必须导入TryStreamExt特征。

fruits以下示例展示了如何实现两个流方法以遍历collection上的查找操作结果:

let mut cursor = my_coll.find(doc! { "color": "red" }).await?;
println!("Output from next() iteration:");
while let Some(doc) = cursor.next().await {
println!("{:?}", doc?);
}
println!();
let mut cursor = my_coll.find(doc! { "color": "yellow" }).await?;
println!("Output from try_next() iteration:");
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Output from next() iteration:
Fruit { name: "strawberry", color: "red" }
Fruit { name: "pomegranate", color: "red" }
Output from try_next() iteration:
Fruit { name: "banana", color: "yellow" }
Fruit { name: "pineapple", color: "yellow" }

由于Cursor类型实现了Stream特征,因此您可以将游标的结果收集到数组中。

您可以使用以下方法以数组形式检索文档:

  • collect():将游标的结果收集为Vec<Result<T>>类型

  • try_collect():将游标的结果收集为Result<Vec<T>>类型

注意

要使用collect()方法,您必须导入StreamExt特征。 要使用try_collect()方法,您必须导入TryStreamExt特征。

let cursor = my_coll.find(doc! { "color": "red" }).await?;
println!("Output from collect():");
let v: Vec<Result<Fruit>> = cursor.collect().await;
println!("{:?}", v);
println!();
let cursor = my_coll.find(doc! { "color": "yellow" }).await?;
println!("Output from try_collect():");
let v: Vec<Fruit> = cursor.try_collect().await?;
println!("{:?}", v);
Output from collect():
[Ok(Fruit { name: "strawberry", color: "red" }), Ok(Fruit { name: "pomegranate", color: "red" })]
Output from try_collect():
[Fruit { name: "banana", color: "yellow" }, Fruit { name: "pineapple", color: "yellow" }]

警告

避免超出应用程序内存限制

避免将大量结果转换为数组。 如果大量超过可用应用程序内存大小,应用应用程序可能会崩溃。 如果需要大型结果设立,请分别从游标中检索文档。 要学习;了解如何遍历游标,请参阅本指南的“单独检索文档”部分。

要修改操作返回的游标,请将选项构建器方法链接到返回Cursor实例的方法。 示例,您可以将与游标相关的选项构建器方法链接到find()方法。

注意

设置选项

您可以通过将选项构建器方法直接链接到find()方法调用来设立FindOptions字段。 如果使用的是早期版本的驾驶员,则必须通过将选项构建器方法链接到builder()方法来构造FindOptions实例。 然后,将FindOptions实例作为参数传递给find()

下表描述了与游标相关的选项,您可以通过调用相应的构建器方法来设立这些选项:

设置
说明
batch_size
Specifies the maximum number of documents the server returns per cursor batch. This option sets the number of documents the cursor keeps in memory rather than the number of documents the cursor returns.

Type: u32
Default: 101 documents initially, 16 MB maximum for subsequent batches
cursor_type
Specifies the type of cursor to return. You can set this option to produce a tailable cursor. To learn more about tailable cursors, see Tailable Cursors in the Server manual.

Type: CursorType
Default: CursorType::NonTailable
no_cursor_timeout
Specifies whether the server closes the cursor after a period of inactivity.

重要

由于Cursor类型实现了Drop特征,因此服务器会在游标超出作用域时将其关闭。 服务器运行异步killCursors命令来关闭游标。 请参阅 MongoDB Server手册中的 killCursors 以了解更多信息。

Type: bool
Default: false

以下代码演示如何通过将选项构建器方法链接到find()方法来指定游标相关设置:

let mut cursor = my_coll.find(doc! { "color": "red" })
.batch_size(5)
.cursor_type(CursorType::Tailable)
.no_cursor_timeout(true)
.await?;

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

要了解有关 Rust 类型和 BSON 之间转换的更多信息,请参阅数据建模和序列化指南。

要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档:

后退

指定查询