Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

$text(自我管理部署)

在此页面上

  • 定义
  • 兼容性
  • 语法
  • 行为
  • 示例

注意

本页介绍自托管(非 Atlas)部署的文本查询功能。对于MongoDB Atlas上托管的数据, MongoDB提供改进的全文查询解决方案 Atlas Search和向量搜索解决方案Atlas Vector Search。

本页介绍 $text 操作符,此操作符用于自我管理的部署。

$text

$text 对使用文本索引进行索引的字段内容执行文本查询。

可以使用 $text 查找托管在以下环境中的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

$text 表达式的语法如下:

{
$text: {
$search: <string>,
$language: <string>,
$caseSensitive: <boolean>,
$diacriticSensitive: <boolean>
}
}

$text 运算符接受包含以下字段的文本查询文档:

字段
类型
说明

$search

字符串

MongoDB解析并用于查询文本索引的术语字符串。除非您将术语指定为短语,否则MongoDB对这些术语执行逻辑OR 查询。有关该字段的更多信息,请参阅行为。

$language

字符串

可选。用于确定查询停用词列表以及词干分析器和分词器规则的语言。如果未指定,MongoDB 将使用索引的默认语言。有关支持的语言,请参阅自管理部署中的文本搜索语言

如果将 default_language 值指定为 none,文本索引会解析字段中的每个词,包括停用词,并忽略后缀词干。

$caseSensitive

布尔

可选。用于启用或禁用区分大小写的布尔标志。默认值为 false。如果未指定,则 MongoDB 将遵循文本索引的不区分大小写的规则。

有关详细信息,请参阅不区分大小写。

$diacriticSensitive

布尔

可选。一个布尔标志,用于启用或禁用针对版本 3 文本索引的变音符号敏感性。默认为 false。如果未指定,MongoDB 将遵循文本索引的变音符号不敏感性。

针对早期版本的文本索引的文本查询本质上是区分变音符号的,并且不能不区分变音符号。因此,$diacriticSensitive 选项对早期版本的 text 索引没有影响。

有关更多信息,请参阅不区分变音符号。

默认情况下,$text 运算符不会返回按结果分数排序的结果。有关按结果分数排序的更多信息,请参阅文本分数文档。

  • 一个查询最多只能指定一个 $text 表达式。

  • $text 不能出现在 $nor 表达式中。

  • $text 不能出现在 $elemMatch 查询表达式或 $elemMatch 投影表达式中。

  • 要在 $or 表达式中使用 $text,必须为 $or 数组中的所有子句创建索引。

  • 如果查询包含 $text 表达式,则不能使用 hint() 指定用于查询的索引。

  • 如果查询包含 $text 表达式,则不能指定 $natural 排序顺序。

  • 不能将需要特殊文本索引$text 表达式与需要其他类型特殊索引的查询操作符组合使用。例如,不能 $text 表达式与 $near 运算符组合使用。

  • 视图不支持 $text

  • $text 不支持使用 Stable API V1 创建索引。

如果在聚合中使用 $text 运算符,则以下限制也同样适用。

  • 包含 $text$match 阶段必须是管道中的第一个阶段。

  • $text 操作符在此阶段只能出现一次。

  • $text 操作符表达式不能出现在 $or$not 表达式中。

  • $text,默认情况下不会按照匹配分数的顺序返回匹配文档。要按分数降序排序,请在 $sort 阶段使用 $meta 聚合表达式。

$search 字段中,指定 $text 运算符解析并用于查询文本索引的字串。

$text 运算符会将该字符串中的大多数标点符号视为分隔符,但用于否定术语的连字符减号 (-) 或用于指定短语的转义双引号 \" 除外。

注意

用于 $text 表达式的 $search 字段与 Atlas Search 提供的 $search 聚合阶段 不同。$search 聚合阶段会对指定的字段执行全文搜索,且仅在 MongoDB Atlas 上可用。

要匹配短语(而不是单个词),请将短语包含在转义双引号 (\") 中,如下所示:

"\"ssl certificate\""

如果 $text 操作的 $search 字符串包含短语和单个词,$text 仅会匹配包含该短语的文档。

例如,传递了一个 $search 字符串:

"\"ssl certificate\" authority key"

$text 操作符返回包含短语 "ssl certificate" 的文档。

注意

您不能搭配多个短语使用 $text 操作符。

在单词前面加上连字符减号 (-) 可以否定单词:

  • 否定词从结果集中排除包含否定词的文档。

  • 当传递仅包含否定词的字符串时,$text 不会匹配任何文档。

  • 带连字符的单词,例如 pre-market,不是否定词。如果在带连字符的单词中使用,$text 操作符会将减号连字符(-)视为分隔符。要在本例中否定单词 market,请在 pre-market 之间添加一个空格,即 pre -market

$text 操作符使用逻辑 AND 操作符将所有否定词添加到操作中。

$text 操作符会忽略特定语言的停用词,例如英语中的 theand

对于不区分大小写和不区分变音符号的搜索,$text 操作符会匹配完整的词干。如果文档字段包含单词 blueberry ,则 $search 词为 blue$text 操作不匹配。然而,blueberryblueberries 匹配。

当您使用区分大小写 ($caseSensitive: true) 时,如果后缀词干包含大写字母,则 $text 操作符将匹配准确的单词。

当您使用区分变音符号$diacriticSensitive: true)时,如果后缀词干包含一个或多个变音标记,则 $text 操作符会匹配准确的单词。

$text 操作符默认为文本索引不区分大小写:

  • 版本 3 的文本索引对带或不带变音符号的拉丁字符以及来自非拉丁字母的字符(例如西里尔字母)不区分大小写。请参阅文本索引,了解详细信息。

  • 早期版本的 text 索引对于不带变音符号的拉丁字符不区分大小写;即,对于 [A-z]

要在 text 索引不区分大小写时支持区分大小写,请指定 $caseSensitive: true

如果 $caseSensitive: truetext 索引不区分大小写,则 $text 操作符:

  • 首先,查询 text 索引是否存在不区分大小写和变音符号的匹配项。

  • 然后,为了仅返回与指定词语大小写相匹配的文档,$text 操作会包括一个额外的阶段,用于过滤出与指定大小写不匹配的文档。

如果 $caseSensitive: true 并且如果后缀词干包含大写字母,则 $text 操作符将匹配准确的单词。

指定 $caseSensitive: true 可能会影响性能。

提示

另请参阅:

$text 操作符默认为文本索引不区分变音符号:

  • 版本 3 文本索引不区分变音符号。也就是说,索引不区分包含变音标记的字符及其未标记的对应字符,例如éêe

  • 早期版本的 text 索引会区分变音符号。

要支持针对 text 索引进行区分变音符号的搜索,请指定 $diacriticSensitive: true

针对早期版本的 text 索引的文本查询本质上是区分变音符号的,并且不能不区分变音符号。因此,$text 操作符的 $diacriticSensitive 选项对早期版本的 text 索引没有影响。

要对版本 3 text 索引使用区分变音符号 ( $diacriticSensitive: true$text 操作符会:

  • 首先查询 text 索引,该索引不区分变音符号。

  • 然后,为了仅返回与指定词语的变音符号相匹配的文档,$text 操作会包括一个额外的阶段,用于过滤不匹配的文档。

指定 $diacriticSensitive: true 可能会影响性能。

如果将 $diacriticSensitive: true 与早期版本的 text 索引一起使用,则 $text 操作符将查询 text 索引,该索引区分变音符号。

如果 $diacriticSensitive: true 并且如果后缀词干包含变音符号或标记,则 $text 操作符将匹配准确的单词。

提示

另请参阅:

$text 操作符将为每个结果文档分配分数。该分数表示文档与给定查询的相关性。该分数可以是 sort() 方法规范的一部分,也可以是投影表达式的一部分。{ $meta: "textScore" } 表达式提供了有关 $text 操作的处理信息。有关访问投影或排序分数的详细信息,请参见 $meta 投影操作符。

以下示例假设集合 articles 在字段 subject 上具有版本 3 文本索引:

db.articles.createIndex( { subject: "text" } )

用以下文档填充集合:

db.articles.insertMany( [
{ _id: 1, subject: "coffee", author: "xyz", views: 50 },
{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 },
{ _id: 4, subject: "baking", author: "xyz", views: 100 },
{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
{ _id: 6, subject: "Сырники", author: "jkl", views: 80 },
{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
] )

以下示例指定 coffee$search 字符串:

db.articles.find( { $text: { $search: "coffee" } } )

此操作返回在带索引的 subject 字段中包含 coffee 这个词(或更准确地说,该单词的词干版本)的文档:

{ _id: 1, subject: 'coffee', author: 'xyz', views: 50 },
{ _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 },
{ _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 }

提示

另请参阅:

如果 $search 字符串是以空格分隔的字符串,$text 会对每个搜索词执行逻辑 OR 操作,并返回包含任何搜索词的文档。

以下示例指定由空格分隔的三个搜索词组成的 $search 字符串 "bake coffee cake"

db.articles.find( { $text: { $search: "bake coffee cake" } } )

此操作返回带索引的 subject 字段中包含 bakecoffeecake 的文档,或更准确地说,包含这些单词的词干提取版本:

{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 }
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }
{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90 }
{ "_id" : 4, "subject" : "baking", "author" : "xyz", "views" : 100 }

提示

另请参阅:

要将确切的短语作为单个术语进行匹配,需要对引号进行转义。

以下示例匹配短语 coffee shop

db.articles.find( { $text: { $search: "\"coffee shop\"" } } )

此操作会返回包含短语 coffee shop 的文档:

{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }

以下示例匹配短语 coffee shopCafe con Leche 。这是两个短语的逻辑 OR。

db.articles.find( { $text: { $search: "\'coffee shop\' \'Cafe con Leche\'" } } )

此操作返回包含这两个短语的文档,包括包含这两个短语中的字词的文档:

[
{ _id: 8, subject: 'Cafe con Leche', author: 'xyz', views: 10 },
{ _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 },
{ _id: 1, subject: 'coffee', author: 'xyz', views: 50 },
{ _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 },
{ _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 }
]

提示

另请参阅:

否定词是指以减号 - 为前缀的词。如果否定一个词,$text 操作符将从结果中排除包含这些词的文档。

以下示例匹配包含单词 coffee包含搜索词 shop 的文档,或者更准确地说,包含这些单词的词干提取版本:

db.articles.find( { $text: { $search: "coffee -shop" } } )

该操作将返回以下文档:

{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 }
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }

提示

另请参阅:

使用 $text 表达式中可选的 $language 字段指定一种语言,该语言确定停用词列表以及 $search 字符串的词干提取器和分词器规则。

如果将 default_language 值指定为 none,文本索引会解析字段中的每个词,包括停用词,并忽略后缀词干。

以下示例指定 es,即西班牙语,作为决定分词、词干提取和停用词的语言:

db.articles.find(
{ $text: { $search: "leche", $language: "es" } }
)

示例返回以下文档:

{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 }
{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz", "views" : 10 }

$text 表达式也可以接受语言名称 spanish。有关支持的语言,请参阅自管理部署中的文本搜索语言

提示

另请参阅:

$text 操作符遵循 text 索引的不区分大小写和变音符号的特性。版本 3 的 text 索引不区分变音符号,并将其不区分大小写的特性扩大为包括西里尔字母以及带变音符号的字符。有关详细信息,请参阅文本索引不区分大小写文本索引不区分变音符号不敏感

以下示例对搜索词 сы́рникиCAFÉS 执行不区分大小写和变音符号的文本查询:

db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } )

使用版本 3 text 索引,该操作将匹配以下文档。

{ "_id" : 6, "subject" : "Сырники", "author" : "jkl", "views" : 80 }
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 }
{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz", "views" : 10 }

如果使用以前版本的text索引,该查询不会匹配任何文档。

要启用区分大小写,请指定 $caseSensitive: true。指定 $caseSensitive: true 可能会影响性能。

以下示例对搜索词 Coffee 执行区分大小写的查询:

db.articles.find( { $text: { $search: "Coffee", $caseSensitive: true } } )

该操作仅与以下文档匹配:

{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }

以下示例对短语 Café Con Leche 执行区分大小写的查询:

db.articles.find( {
$text: { $search: "\"Café Con Leche\"", $caseSensitive: true }
} )

该操作仅与以下文档匹配:

{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 }

否定词是指以减号 - 为前缀的词。如果否定一个词,$text 运算符将从结果中排除包含这些词的文档。您还可以为否定词指定是否区分大小写。

以下示例对包含单词 Coffee包含小写单词 shop 的文档(或更准确地说,单词的词干版本)执行区分大小写的查询:

db.articles.find( { $text: { $search: "Coffee -shop", $caseSensitive: true } } )

该操作匹配以下文档:

{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg" }

提示

另请参阅:

要对版本 3 文本索引区分变音符号,请指定 $diacriticSensitive: true。指定 $diacriticSensitive: true 可能会影响性能。

以下示例将对 CAFÉ 一词或(更准确地说是)该词的词干版本执行区分变音符号的文本查询:

db.articles.find( { $text: { $search: "CAFÉ", $diacriticSensitive: true } } )

操作只匹配以下文档:

{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc" }

$diacriticSensitive 选项也适用于否定词。否定词是带有负号 - 前缀的词。如果否定一个词,$text 操作符将从结果中排除包含这些词的文档。

以下示例对包含搜索词 leches 但不包含 cafés 一词的文档执行区分变音符号的文本查询,或者更准确地说是这些单词的词干提取版本:

db.articles.find(
{ $text: { $search: "leches -cafés", $diacriticSensitive: true } }
)

该操作匹配以下文档:

{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz" }

以下示例对术语 cake 进行文本查询,并在投影文档中使用 $meta 操作符将相关性分数追加到每个匹配的文档:

db.articles.find(
{ $text: { $search: "cake" } },
{ score: { $meta: "textScore" } }
)

返回的文档包含一个附加 字段 score,其中包含文档的相关性分数:

{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90, "score" : 0.75 }

提示

另请参阅:

  • 您可以在 sort() 中指定 { $meta: "textScore" } 表达式,而无需在投影中指定表达式。例如:

    db.articles.find(
    { $text: { $search: "cake" } }
    ).sort( { score: { $meta: "textScore" } } )

    因此,您可以根据相关性对结果文档进行排序,而无需对 textScore 投影。

  • 如果在投影sort() 中都包含 { $meta: "textScore" } 表达式,则投影和排序文档的表达式可以有不同的字段名。

    For example, in the following operation, the projection uses a field named score for the expression and the sort() uses the field named ignoredName.
    db.articles.find(
    { $text: { $search: "cake" } } ,
    { score: { $meta: "textScore" } }
    ).sort( { ignoredName: { $meta: "textScore" } } )

提示

另请参阅:

limit() 方法与 sort() 结合使用可返回前 n 个匹配的文档。

以下示例查询搜索词 coffee 并按降序分数对结果进行排序,将结果限制为前两个匹配的文档:

db.articles.find(
{ $text: { $search: "coffee" } },
{ score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } ).limit(2)

提示

另请参阅:

以下示例匹配 author 等于 "xyz" 且带索引的字段 subject 包含搜索词 coffeebake 的文档。该操作还指定按 date 升序排列,然后按相关性分数降序排列:

db.articles.find(
{ author: "xyz", $text: { $search: "coffee bake" } },
{ score: { $meta: "textScore" } }
).sort( { date: 1, score: { $meta: "textScore" } } )

后退

文本搜索操作符