文档菜单
文档首页
/
MongoDB 手册
/ / /

$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将取决于文本索引的变音符号不敏感性。

针对早期版本文本索引的文本查询是固有的变音符号敏感的,无法实现变音符号不敏感。因此,在早期版本的 text 索引中,$diacriticSensitive 选项不起作用。

有关更多信息,请参阅变音符号不敏感性。

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

  • 查询最多可以指定一个 $text 表达式。

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

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

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

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

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

  • 不能将$text表达式与需要特殊文本索引的查询运算符结合。例如,不能将$text表达式与$near

  • 运算符结合。

  • 视图不支持$text

使用$text运算符时,以下限制也适用。

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

  • 阶段中只能出现一次$text运算符。

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

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

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

$text运算符将字符串中的大多数标点符号视为分隔符,除了表示否定项的连字符(-)和表示短语的转义双引号(\")。

注意

对于 $text 表达式的 $search 字段与由 $search 聚合阶段 提供的不同,该阶段由 Atlas 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 匹配。

当使用 大小写敏感(《code class="leafygreen-ui-1l06pbn">$caseSensitive: true),如果词干后缀包含大写字母,则 $text 操作符将匹配确切的单词。

当使用 变音符号敏感(《code class="leafygreen-ui-1l06pbn">$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 操作符没有影响。

要使用变音符号敏感度($diacriticSensitive: true)与版本 3 的 text 索引,使用 $text 操作符

  • 首先查询 text 索引,该索引是不敏感于变音符号的。

  • 然后,为了仅返回与指定术语的变音符号标记字符匹配的文档,$text 操作包括一个额外的阶段来过滤掉不匹配的文档。

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

如果您在较早版本的 text 索引上使用 $diacriticSensitive: true,则 $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 }
] )

以下示例指定了一个 $search 字符串,即 coffee

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

此操作返回包含 bake coffee cake 的文档,这些词出现在索引的 subject 字段中,或者更确切地说,是这些词的词根版本

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

要将精确的短语作为一个单独的词匹配,请转义引号。

以下示例匹配短语 咖啡店

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

此操作返回包含短语 咖啡店 的文档

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

以下示例匹配短语 咖啡店卡夫埃康内彻。这是两个短语的逻辑或操作。

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 操作符会从结果中排除包含这些术语的文档。

以下示例匹配包含单词 咖啡 但不包含术语 的文档,或者更精确地说,包含这些单词的词干版本

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

以下示例执行了针对术语 蛋糕 的文本查询,并在投影文档中使用 $meta 操作符将相关性得分附加到每个匹配的文档

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

返回的文档包含一个包含文档相关性得分的 附加 字段 score

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

提示

另请参阅

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

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

    因此,您可以通过相关性对结果文档进行排序,而无需在投影中包含 textScore

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

    例如,在以下操作中,投影使用名为 score 的字段来表示表达式,而 sort() 使用名为 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)

提示

另请参阅

以下示例匹配作者等于"xyz"且索引字段subject包含术语coffeebake的文档。操作还指定了升序排序的date,然后是降序的相关性分数

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

返回

文本搜索运算符