Docs 菜单
Docs 主页
/ / /
Node.js
/ / /

搜索文本

在此页面上

  • 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" });

提示

在文本索引中指定字段权重

创建复合文本索引时,可以指定权重选项,以便在索引中优先处理某些文本字段。当您执行文本搜索时,字段权重会影响 MongoDB 如何计算每个匹配文档的文本搜索分数

要学习;了解有关在创建文本索引时指定字段权重的更多信息,请参阅索引指南中的文本索引部分。

每个集合只能创建一个文本索引。每个文本搜索都会查询该索引中指定的所有字段以查找匹配项。

要了解有关文本索引的更多信息,请参阅服务器手册中的文本索引

此示例通过搜索包含 "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 操作符及其选项的更多信息,请参阅手册条目

后退

按地理空间搜索