文档菜单
文档首页
/ / /
Node.js 驱动程序
/ / /

文本搜索

本页内容

  • 概述
  • 示例
  • 按单词查询
  • 按短语查询
  • 使用否定查询
  • 按相关性排序

文本搜索允许您在集合中搜索指定单词或短语的字符串类型字段。您可以通过使用以下方式执行文本搜索:$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)。

// Create a query that searches for the string "trek"
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>\"

// Create a query that searches for the phrase "star trek"
const query = { $text: { $search: "\"star trek\"" } };
// Return only the `title` of each matched document
const projection = {
_id: 0,
title: 1,
};
// Find documents based on the query and projection
const cursor = movies.find(query).project(projection);

与仅使用术语"trek"相比,按短语"star 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"的所有电影,在这种情况下,结果仅限于虚构的《星际迷航》电影。不幸的是,此查询返回了"Star Trek Into Darkness"这部电影,它不是原始电影系列的一部分。为了解决这个问题,我们可以使用否定来排除该文档。

要使用否定词,在要排除的结果集中出现的术语前放置一个负号 -。查询操作会从搜索结果中排除包含此术语的任何文档。由于此查询包含两个不同的术语,请用空格将它们分开。

// Create a query that searches for the phrase "star trek" while omitting "into darkness"
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 the 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 来按相关性对结果进行排序

// Create a query that searches for the phrase "star trek" while omitting "into darkness"r
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 the 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 操作符及其选项的更多信息,请参阅手册条目。

返回

地理空间搜索