Docs HomeNode.js

Search Text搜索文本

Overview概述

Text search, using the $text query operator, lets you search string type fields in your collection for words or phrases. 使用$Text查询运算符进行文本搜索,可以在集合中的字符串类型字段中搜索单词或短语。This operator performs a logical OR on each term separated by a space in the search string. 此运算符对搜索字符串中由空格分隔的每个项执行逻辑OR运算。You can also specify additional options to the operator to handle case sensitivity, stop words, and word stemming (such as plural forms or other tenses) for a supported language. 您还可以为运算符指定其他选项,以处理支持语言的区分大小写、停止词和词干(如复数形式或其他时态)。This is particularly useful for unstructured text such as transcripts, essays, or web pages.这对于非结构化文本(如成绩单、文章或网页)特别有用。

The $text query operator requires that you specify the search field in a text index on your collection. $text查询运算符要求您在集合的文本索引中指定搜索字段。See the examples below for sample code for creating a text index and using the $text query operator.有关创建文本索引和使用$text查询运算符的示例代码,请参阅下面的示例。

Note

Atlas Search makes it easy to build fast, relevance-based search capabilities on top of your MongoDB data. 可以轻松地在MongoDB数据之上构建快速、基于相关性的搜索功能。Try it today on MongoDB Atlas, our fully managed database as a service.今天就在MongoDB Atlas上试试吧,这是全托管数据库即服务。

Examples实例

The following examples use sample data from the movies collection in the sample_mflix database. 以下示例使用sample_mflix数据库中movies集合的示例数据。In order to enable text searches on the title field, create a text index by using the following command:要在title字段上启用文本搜索,请使用以下命令创建文本索引

db.movies.createIndex({ title: "text" });

We use a single field text index for the examples in this guide, but you can create a compound text index that broadens your text queries to multiple fields. 对于本指南中的示例,我们使用单字段文本索引,但您可以创建一个复合文本索引,将文本查询扩展到多个字段。The following command creates a text index on two fields in the movies collection:以下命令在movies集合中的两个字段上创建文本索引:

db.movies.createIndex({ title: "text", plot: "text" });
Tip

Specify Field Weights in a Text Index指定文本索引中的字段权重

When creating a compound text index, you can specify a weight option to prioritize certain text fields in your index. 创建复合文本索引时,可以指定权重选项,以对索引中的某些文本字段进行优先级排序。When you execute a text search, the field weights influence how MongoDB calculates the text search score for each matching document.当您执行文本搜索时,字段权重会影响MongoDB计算每个匹配文档的文本搜索分数的方式。

To learn more about specifying field weights when creating a text index, see the Text Indexes section in the Indexes guide.要了解有关在创建文本索引时指定字段权重的详细信息,请参阅指南的“索引”部分中的文本索引部分。

You can only create one text index per collection. 每个集合只能创建一个文本索引。Every text search queries all the fields specified in that index for matches.每次文本搜索都会查询该索引中指定的所有字段以查找匹配项。

To learn more about text indexes, see Text Indexes in the Server manual.要了解有关文本索引的详细信息,请参阅服务器手册中的文本索引

Query for Words查询单词

This example queries for Star Trek movies by searching for titles containing the word "trek". 本例通过搜索包含单词“Trek”的标题来查询“Star Trek”(星际迷航)电影。If you want to query using multiple words, separate your words with spaces to query for documents that match any of the search terms (logical OR).如果要使用多个单词进行查询,请用空格分隔单词,以查询与任何搜索词匹配的文档(逻辑OR)。

  const query = { $text: { $search: "trek" } };

// Return only the `title` of each matched document只返回每个匹配文档的`title`
const projection = {
_id: 0,
title: 1,
};

// find documents based on our query and projection根据查询和投影查找文档
const cursor = movies.find(query).project(projection);

This operation returns the following documents:此操作返回以下文档:

{ 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' }

Success! The query found every document in the movies collection with a title including the word "trek". 成功查询发现,movies集合中的每一份文件都有一个标题,其中包括“trek”一词。Unfortunately, the search included one unintended item: "Trek Nation," which is a movie about Star Trek and not part of the Star Trek movie series. 不幸的是,搜索中包含了一个意想不到的项目:“Trek Nation,”,这是一部关于星际迷航的电影,不是星际迷航系列电影的一部分。To solve this, we can query with a more specific phrase.为了解决这个问题,我们可以使用更具体的短语进行查询。

Query By Phrase按短语查询

To make your query more specific, try using the phrase "star trek" instead of just the word "trek". 要使查询更加具体,请尝试使用短语“star trek”,而不仅仅是“trek”一词。To search by phrase, surround your multi-word phrase with escaped quotes (\"<term>\"):要按短语搜索,请用转义引号(\"<term>\")将多词短语括起来:

  const query = { $text: { $search: "\"star trek\"" } };

// Return only the `title` of each matched document只返回每个匹配文档的`title`
const projection = {
_id: 0,
title: 1,
};

// find documents based on our query and projection根据查询和投影查找文档
const cursor = movies.find(query).project(projection);

Querying by the phrase "star trek" instead of just the term "trek" matches the following documents:通过短语“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' }

These results include all movies in the database that contain the phrase "star trek", which in this case results in only fictional Star Trek movies. 这些结果包括数据库中包含短语“星际迷航”的所有电影,在这种情况下,这只会导致虚构的星际迷航电影。Unfortunately, though, this query returned "Star Trek Into Darkness", a movie that was not part of the original series of movies. 然而,不幸的是,这个查询返回了《星际迷航:进入黑暗》,这部电影并不是最初系列电影的一部分。To resolve this issue, we can omit that document with a negation.为了解决这个问题,我们可以用否定的方式省略该文件。

Query with Negations带否定的查询

To use a negated term, place a negative sign (-) in front of the term you would like to omit from the result set. 要使用否定项,请在要从结果集中省略的项前面放一个负号(-)。The query operation omits any documents that contain this term from the search result. 查询操作会从搜索结果中省略任何包含此术语的文档。Since this query includes two distinct terms, separate them with a space.由于此查询包含两个不同的术语,请用空格将它们隔开。

  const query = { $text: { $search: "\"star trek\"  -\"into darkness\"" } };

// Include only the `title` field of each matched document只包括每个匹配文档的`title`
const projection = {
_id: 0,
title: 1,
};

// find documents based on our query and projection根据查询和投影查找文档
const cursor = movies.find(query).project(projection);

Querying with the negated term yields the following documents:使用否定项进行查询会生成以下文档:

{ 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' }
Note

Your query operation may return a reference to a cursor that contains matching documents. 您的查询操作可能会返回对包含匹配文档的游标的引用。To learn how to examine data stored in the cursor, see the Cursor Fundamentals page.要了解如何检查存储在游标中的数据,请参阅游标基础页面。

Sort by Relevance按相关性排序

Now that the result set reflects the desired results, you can use the text search textScore, accessed using the $meta operator in the query projection, to order the results by relevance:既然结果集反映了所需的结果,您可以使用文本搜索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在每个返回的文档中只包括`title`和`score`字段
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);

Querying in this way returns the following documents in the following order. 以这种方式查询将按以下顺序返回以下文档。In general, text relevance increases as a string matches more terms and decreases as the unmatched portion of the string lengthens.通常,文本相关性会随着字符串匹配更多术语而增加,而随着字符串中不匹配部分的长度增加而减少。

{ 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 }

For more information about the $text operator and its options, see the manual entry.有关$text运算符及其选项的更多信息,请参阅手动条目