搜索文本
Overview
通过 $text
查询操作符进行文本搜索,您可以在集合的字符串类型字段中查找单词或短语。此操作符将对搜索字符串中每个以空格分隔的词项进行逻辑 OR
操作。您还可以为操作符指定额外的选项,以处理大小写敏感性、停用词和词干提取(例如复数形式或不同时态)以适应特定语言。这对于非结构化文本(例如文字转录、文章或网页)特别有用。
$text
查询运算符要求你在集合上的文本索引中指定搜索字段。有关创建文本索引和使用 $text
查询运算符的示例代码,请参阅以下示例。
注意
Atlas Search 使您可以轻松地基于 MongoDB 数据,构建运行快速且极具相关性的搜索功能。立即在完全托管的数据库即服务 MongoDB Atlas 上试一试。
示例
以下示例使用 sample_mflix
数据库中 movies
集合的样本数据。为了在 title
字段上启用文本搜索,请使用以下命令创建文本索引:
db.movies.createIndex({ title: "text" });
对于本指南中的示例,我们使用单个字段文本索引,但您也可创建复合文本索引,从而将文本查询的范围延伸到多个字段。以下命令将对 movies
集合中的两个字段创建文本索引:
db.movies.createIndex({ title: "text", plot: "text" });
提示
在文本索引中指定字段权重
每个集合只能创建一个文本索引。每个文本搜索都会查询该索引中指定的所有字段以查找匹配项。
要了解有关文本索引的更多信息,请参阅服务器手册中的文本索引。
单词查询
此示例通过搜索包含 "trek" 一词的标题来查询《星际迷航》电影。如果要使用多个单词进行查询,请使用空格分隔单词,以查询与任何搜索词(逻辑 OR
)匹配的文档。
const query = { $text: { $search: "trek" } }; // Return only the `title` of each matched document const projection = { _id: 0, title: 1, }; // find documents based on our query and projection const cursor = movies.find(query).project(projection);
该操作将返回以下文档:
{ title: 'Trek Nation' } { title: 'Star Trek' } { title: 'Star Trek Into Darkness' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
成功!该查询找到了 movies
集合中标题包含 "trek" 一词的所有文档。但遗憾的是,搜索发现一个意外条目 "Trek Nation",这是一部介绍《星际迷航》的电影,而不属于该电影系列。为解决这个问题,我们可以使用更具体的短语进行查询。
按短语查询
为了使查询更具体,请尝试使用 "star trek" 短语替代 "trek" 一词。要按短语搜索,请用转义引号 (\"<term>\"
) 将多词短语括起来:
const query = { $text: { $search: "\"star trek\"" } }; // Return only the `title` of each matched document const projection = { _id: 0, title: 1, }; // find documents based on our query and projection const cursor = movies.find(query).project(projection);
通过短语“star trek”而不是仅使用“trek”一词来进行查询可匹配以下文档:
{ title: 'Star Trek' } { title: 'Star Trek Into Darkness' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
结果列表给出数据库中包含短语 "star trek" 的所有电影,在本例中仅为虚构的《星际迷航》电影。但这个查询返回了《星际迷航:暗黑无界》,这部电影不属于原始《星际迷航》电影系列。为解决这个问题,我们可以用否定词来省略该文档。
带否定词的查询
要使用否定词,在您希望从结果集中忽略的词前面放置一个负号 (-
)。查询操作会从搜索结果中忽略所有包含该词的文档。由于此查询包含两个非重复的词,因此要使用空格将其分隔。
const query = { $text: { $search: "\"star trek\" -\"into darkness\"" } }; // Include only the `title` field of each matched document const projection = { _id: 0, title: 1, }; // find documents based on our query and projection const cursor = movies.find(query).project(projection);
使用否定词进行查询会产生以下文档:
{ title: 'Star Trek' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
注意
您的查询操作可能会返回对包含匹配文档的游标的引用。要了解如何检查存储在游标中的数据,请参阅游标基础知识页面。
按相关性排序
既然结果集体现了所需的结果,您可以使用文本搜索 textScore
(在查询投影中使用 $meta 操作符进行访问)按相关性对结果排序:
const query = { $text: { $search: "\"star trek\" -\"into darkness\"" } }; // sort returned documents by descending text relevance score const sort = { score: { $meta: "textScore" } }; // Include only the `title` and `score` fields in each returned document const projection = { _id: 0, title: 1, score: { $meta: "textScore" }, }; // find documents based on our query, sort, and projection const cursor = movies .find(query) .sort(sort) .project(projection);
以这种方式查询将按以下顺序返回以下文档。通常,文本相关性随着字符串匹配更多术语而增加,而随着字符串中不匹配部分的增加,文本的相关性会降低。
{ title: 'Star Trek', score: 1.5 } { title: 'Star Trek: Generations', score: 1.3333333333333333 } { title: 'Star Trek: Insurrection', score: 1.3333333333333333 } { title: 'Star Trek: Nemesis', score: 1.3333333333333333 } { title: 'Star Trek: The Motion Picture', score: 1.25 } { title: 'Star Trek: First Contact', score: 1.25 } { title: 'Star Trek II: The Wrath of Khan', score: 1.2 } { title: 'Star Trek III: The Search for Spock', score: 1.2 } { title: 'Star Trek IV: The Voyage Home', score: 1.2 } { title: 'Star Trek V: The Final Frontier', score: 1.2 } { title: 'Star Trek VI: The Undiscovered Country', score: 1.2 }
有关 $text 操作符及其选项的更多信息,请参阅手册条目。