对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

查询文本

在本指南中,您可以学习如何使用Rust驱动程序运行文本查询。文本查询可让您高效地查询具有 string 值的字段。

重要

MongoDB text queries differ from the more powerful MongoDB Search feature. To learn more, see the MongoDB Search documentation.

本指南包括以下部分:

  • 示例的样本数据显示文本查询示例使用的示例数据

  • Text Index describes how to create a text index on a string-valued field

  • 文本查询描述如何使用不同的搜索条件执行文本查询

  • 聚合描述了如何使用聚合管道执行文本查询

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

本指南中的示例使用以下 Dish 结构作为 menu 集合中文档的模型:

#[derive(Serialize, Deserialize, Debug)]
struct Dish {
name: String,
description: String,
}

这些示例使用以下样本文档描述您可以在餐厅点的菜品:

{ "name": "Shepherd’s Pie", "description": "A vegetarian take on the classic dish that uses lentils as a base. Serves 2." },
{ "name": "Green Curry", "description": "A flavorful Thai curry, made vegetarian with tofu. Vegetarian and vegan friendly." },
{ "name": "Herbed Branzino", "description": "Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4." },
{ "name": "Kale Tabbouleh", "description": "A bright, herb-based salad. A perfect starter for vegetarians and vegans." },
{ "name": "Garlic Butter Trout", "description": "Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2." }

在执行文本查询之前,必须在集合上创建文本索引。文本索引指定可以执行文本查询的字符串或字符串大量字段。

本指南中的示例对 menu集合中文档的 description字段执行文本查询。要启用对 description字段的文本查询,请创建文本索引,如以下代码所示:

let index = IndexModel::builder()
.keys(doc! { "description": "text" })
.build();
let idx_res = my_coll.create_index(index, None).await?;

文本查询检索在索引字段的值中包含指定术语或短语的文档。术语是不包括空白字符的字符序列。短语是具有任意数量的空白字符的一系列术语。

要执行文本查询,请在查询过滤中包含 $text 评估查询运算符,然后是 $search字段。$text操作符指定您正在对文本索引字段执行文本查询。$search字段指定要在一个或多个文本索引字段中搜索的术语或短语。

文本查询筛选器使用以下格式:

let filter = doc! { "$text": { "$search": "<search term or phrase>" } };

要搜索某个术语,请在查询筛选器中将该术语指定为字符串。要搜索多个术语,请用空格分隔每个术语。

注意

搜索多个术语时, find()方法会返回文本索引字段至少包含其中一个术语的任何文档。

例如,如果您的搜索术语是"one two three" ,MongoDB 将返回索引字段包含"one" 、 "two" 、 "three"或多个这些术语的文档。

以下示例执行对description字段包含术语"herb"的文档的搜索:

let filter = doc! { "$text": { "$search": "herb" } };
let mut cursor = my_coll.find(filter, None).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}

提示

即使搜索术语是 "herb",文本查询也会匹配 description字段包含 "herbs" 的文档。这是因为MongoDB文本索引使用后缀词干来匹配相似的单词。要学习;了解有关MongoDB如何匹配术语的更多信息,请参阅服务器手册中的索引项。

要搜索短语,请在查询筛选器中指定带有转义引号的短语:

let filter = doc! { "$text": { "$search": "\"<some phrase>\"" } };

If you don't add escaped quotes around the phrase, the search performs a term search.

以下示例搜索description字段包含短语"serves 2"的文档:

let filter = doc! { "$text": { "$search": "\"serves 2\"" } };
let mut cursor = my_coll.find(filter, None).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}

要指定要从文本查询中排除的术语或短语,请在查询过滤中使用减号作为前缀:

let filter = doc! { "$text": { "$search": "<term> -<excluded term>" } };

重要

您必须至少搜索一个术语或短语才能从搜索中排除其他术语。如果仅排除术语,则搜索不会返回任何文档。

以下示例搜索description字段包含词语"vegan"但不包含词语"tofu"的文档:

let filter = doc! { "$text": { "$search": "vegan -tofu" } };
let mut cursor = my_coll.find(filter, None).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}

文本查询会分配一个数字文本分数,以指示每个结果与查询过滤中的字符串的匹配程度。 文本分数越高,表示结果与您的查询越相关。要显示输出中的文本分数,请使用投影从元数据中检索textScore字段。您可以通过在 textScore元数据字段上指定排序来按降序对文本分数进行排序。

此示例将执行以下动作:

  • 搜索 description 字段包含词语 "vegetarian" 的文档

  • 按文本分数降序对结果进行排序

  • 仅包含输出中的name和score字段

let filter = doc! { "$text": { "$search": "vegetarian" } };
let sort = doc! { "score": { "$meta": "textScore" } };
let projection =
doc! {
"_id": 0,
"name": 1,
"score": { "$meta": "textScore" }
};
let opts = FindOptions::builder().sort(sort).projection(projection).build();
let doc_coll: Collection<Document> = my_coll.clone_with_type();
let mut cursor = doc_coll.find(filter, opts).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}

You can include the $text evaluation query operator in a $match aggregation stage to perform a text query in an aggregation pipeline.

以下部分演示如何使用聚合管道而不是 find() 方法执行文本查询。

以下示例使用聚合搜索description字段包含词语"herb"的文档:

let match_stage = doc! { "$match": { "$text": { "$search": "herb" } } };
let mut cursor = my_coll.aggregate([match_stage], None).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}

此示例使用聚合来执行以下操作:

  • 搜索 description 字段包含词语 "vegetarian" 的文档

  • 按文本分数降序对结果进行排序

  • 仅包含输出中的name和score字段

let match_stage = doc! { "$match": { "$text": { "$search": "vegetarian" } } };
let sort_stage = doc! { "$sort": { "score": { "$meta": "textScore" } } };
let proj_stage =
doc! { "$project": {
"_id": 0,
"name": 1,
"score": { "$meta": "textScore" }
} };
let pipeline = [match_stage, sort_stage, proj_stage];
let mut cursor = my_coll.aggregate(pipeline, None).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}

有关使用find()方法的可运行示例,请参阅“查找多个文档”用法示例。

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

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