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

使用游标访问数据

在此页面上

  • 概述
  • 示例样本数据
  • 分别检索文档
  • 内置模式
  • 流实现模式
  • 以数组形式检索文档
  • 指定游标行为
  • 更多信息
  • 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" }, None).await?;
while cursor.advance().await? {
println!("{:?}", cursor.deserialize_current()?);
}

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

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" }, None).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" }, None).await?;
println!("Output from try_next() iteration:");
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}

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

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

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

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

注意

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

let cursor = my_coll.find(doc! { "color": "red" }, None).await?;
println!("Output from collect():");
let v: Vec<Result<Fruit>> = cursor.collect().await;
println!("{:?}", v);
println!();
let cursor = my_coll.find(doc! { "color": "yellow" }, None).await?;
println!("Output from try_collect():");
let v: Vec<Fruit> = cursor.try_collect().await?;
println!("{:?}", v);

警告

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

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

要修改操作返回的游标,请将选项传递给返回Cursor实例的方法。 例如,您可以在传递给find()方法的FindOptions类型中指定与游标相关的选项。

注意

实例化选项

Rust 驱动程序实现了用于创建许多不同类型的 Builder 设计模式,包括FindOptions 。 您可以使用每种类型的builder()方法,通过逐个链接选项构建器函数来构造选项实例。

下表描述了您可以在选项实例中设置的与游标相关的选项:

设置
说明
batch_size
指定服务器在每个游标批处理中返回的最大文档数。 此选项设置游标在内存中保留的文档数,而不是游标返回的文档数。

类型: u32
默认:最初有101个文档,后续批处理的最大数量为16 MB
cursor_type
指定要返回的游标类型。 您可以设置此选项以生成可追加游标。 要了解有关可追加游标的更多信息,请参阅 MongoDB Server手册中的 可追加游标 。

类型: CursorType
默认: CursorType::NonTailable
no_cursor_timeout
指定服务器在一段时间不活动后是否关闭游标。

重要

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

类型: bool
默认: false

以下代码展示了如何构造FindOptions实例并指定与游标相关的设置:

let opts: FindOptions = FindOptions::builder()
.batch_size(5)
.cursor_type(CursorType::Tailable)
.no_cursor_timeout(true)
.build();

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

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

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

← 指定查询