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

搜索文本

在此页面上

  • Overview
  • 示例样本数据
  • Text Index
  • 文本搜索(Text Search)
  • 搜索词语
  • 搜索短语
  • 从搜索中排除术语
  • 按相关性排序
  • 聚合(Aggregation)
  • 匹配搜索词
  • 按相关性排序
  • 更多信息
  • API 文档

在本指南中,您可以了解如何使用 Rust 驱动程序运行文本搜索。 文本搜索可让您高效地查询具有字符串值的字段。

重要

MongoDB文本Atlas Search与更强大的Atlas Search功能不同。 要了解详情,请参阅 Atlas Search 文档。

本指南包括以下部分:

  • 示例的样本数据显示Atlas Search示例文本使用的样本数据

  • 文本索引介绍如何在字符串值字段上创建文本索引

  • 文本Atlas Search描述了如何使用不同的Atlas Search标准执行文本搜索

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

  • 附加信息提供了本指南中提到的类型和方法的资源和 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." }

在执行搜索之前,必须在collection上创建文本索引。文本索引指定可以执行文本搜索的字符串或字符串数组字段。

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

let index = IndexModel::builder()
.keys(doc! { "description": "text" })
.build();
let idx_res = my_coll.create_index(index).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).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Dish { name: "Kale Tabbouleh", description: "A bright, herb-based salad. A perfect starter for vegetarians and vegans." }
Dish { name: "Herbed Branzino", description: "Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4." }

提示

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

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

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

如果您不在短语两边添加转义引号, Atlas Search将执行术语Atlas Search 。

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

let filter = doc! { "$text": { "$search": "\"serves 2\"" } };
let mut cursor = my_coll.find(filter).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Dish { name: "Shepherd’s Pie", description: "A vegetarian take on the classic dish that uses lentils as a base. Serves 2." }
Dish { name: "Garlic Butter Trout", description: "Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2." }

要指定要从搜索中排除的术语或短语,请在查询筛选器中使用减号作为前缀:

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).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Dish { name: "Kale Tabbouleh", description: "A bright, herb-based salad. A perfect starter for vegetarians and vegans." }

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

此示例将执行以下动作:

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

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

  • 仅包含输出中的namescore字段

let filter = doc! { "$text": { "$search": "vegetarian" } };
let sort = doc! { "score": { "$meta": "textScore" } };
let projection =
doc! {
"_id": 0,
"name": 1,
"score": { "$meta": "textScore" }
};
let doc_coll: Collection<Document> = my_coll.clone_with_type();
let mut cursor = doc_coll.find(filter)
.sort(sort)
.projection(projection)
.await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Document({"name": String("Green Curry"), "score": Double(0.9166666666666667)})
Document({"name": String("Kale Tabbouleh"), "score": Double(0.5625)})
Document({"name": String("Shepherd’s Pie"), "score": Double(0.5555555555555556)})

您可以在$match聚合阶段包含$text评估查询运算符,以在聚合管道中执行文本搜索。

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

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

let match_stage = doc! { "$match": { "$text": { "$search": "herb" } } };
let mut cursor = my_coll.aggregate([match_stage]).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Document({"_id": ObjectId("..."), "name": String("Kale Tabbouleh"), "description": String("A bright, herb-based salad. A perfect starter for vegetarians and vegans.")})
Document({"_id": ObjectId("..."), "name": String("Herbed Branzino"), "description": String("Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4.")})

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

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

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

  • 仅包含输出中的namescore字段

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).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Document({"name": String("Green Curry"), "score": Double(0.9166666666666667)})
Document({"name": String("Kale Tabbouleh"), "score": Double(0.5625)})
Document({"name": String("Shepherd’s Pie"), "score": Double(0.5555555555555556)})

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

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

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

后退

打开变更流