搜索文本
在此页面上
Overview
在本指南中,您可以了解如何使用 Rust 驱动程序运行文本搜索。 文本搜索可让您高效地查询具有字符串值的字段。
重要
MongoDB文本Atlas Search与更强大的Atlas Search功能不同。 要了解详情,请参阅 Atlas Search 文档。
本指南包括以下部分:
示例的样本数据显示Atlas Search示例文本使用的样本数据
文本索引介绍如何在字符串值字段上创建文本索引
文本Atlas Search描述了如何使用不同的Atlas Search标准执行文本搜索
聚合描述了如何使用聚合管道执行文本搜索
附加信息提供了本指南中提到的类型和方法的资源和 API 文档链接
示例样本数据
本部分的示例使用以下 Dish
结构作为 menu
集合中文档的模型:
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." }
Text Index
在执行搜索之前,必须在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
字段。 $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"
的文档按文本分数降序对结果进行排序
仅包含输出中的
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 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)})
聚合(Aggregation)
您可以在$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"
的文档按文本分数降序对结果进行排序
仅包含输出中的
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).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()
方法的可运行示例,请参阅查找多个文档用法示例。
要了解有关本指南中操作的更多信息,请参阅以下文档:
服务器手册中的文本索引
手册中的 $textMongoDB Server
服务器手册中的$meta
API 文档
要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档: