注意
本页介绍自托管(非 Atlas)部署的文本查询功能。 对于MongoDB Atlas上托管的数据, MongoDB提供改进的全文查询解决方案 Atlas Search和向量搜索解决方案Atlas Vector Search。
本页介绍 $text 操作符,此操作符用于自我管理的部署。
定义
$text$text对使用 文本索引进行索引的字段执行文本查询。
兼容性
可以使用 $text 查找托管在以下环境中的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
$text 表达式的语法如下:
{ $text: { $search: <string>, $language: <string>, $caseSensitive: <boolean>, $diacriticSensitive: <boolean> } }
$text操作符接受以下字段:
字段 | 类型 | 说明 |
|---|---|---|
| 字符串 | |
| 字符串 | |
| 布尔 | 可选。启用区分大小写。默认为 |
| 布尔 | 可选。为版本 3文本索引启用区分变音符号。默认为 |
行为
限制
一个查询只能指定一个
$text表达式。$text不能出现在$nor表达式中。$text不能出现在$elemMatch查询或投影表达式中。$or必须对所有 子句编制索引才能使用$text。如果查询包含
$text表达式,则不能使用hint()指定用于查询的索引。$text使用 的查询不能使用$natural排序。不能将需要特殊文本索引的
$text表达式与需要其他类型特殊索引的查询操作符组合使用。例如,不能$text表达式与$near运算符组合使用。视图不支持
$text。Stable API V1 不支持
$text进行索引创建。
如果在聚合中使用 $text 运算符,则以下限制也同样适用。
$search 字段
在$search 字段中,指定MongoDB用于查询文本索引的单词。
注意
$search字段与MongoDB Atlas $ 搜索聚合阶段不同。$search 阶段提供全文搜索,并且仅在MongoDB Atlas上可用。
精确字符串
要匹配精确的多单词字符串而不是单个术语,请将字符串括在转义双引号 (\") 中:如下所示:
"\"ssl certificate\""
如果 $text 操作的 $search 字符串包含多词字符串和单个词,$text 仅会匹配包含该多词字符串的文档。
示例,此 $search 字符串返回具有完全相同的字符串 "ssl certificate" 的文档:
"\"ssl certificate\" authority key"
否定
在单词前缀加上连字符减号 (-) 可对其表示否定:
否定词会从结果设立排除包含否定词的文档。
仅包含否定词的字符串不匹配任何文档。
像
pre-market这样的带连字符的单词不是否定词。 MongoDB将连字符视为分隔符。要取反market,请使用pre -market。
MongoDB将所有否定应用于具有逻辑 AND 的操作。
匹操作
非索引字
MongoDB会忽略特定语言的停用词,例如英语中的 the 和 and。
词干处理
由于不区分大小写和变音符号,$text 会匹配完整的词干词。如果文档字段包含blueberry ,则$search 的blue 术语不匹配。但是,blueberry 或blueberries 会匹配。
区分大小写和词干
启用区分大小写 ($caseSensitive: true) 后,如果后缀词干包含大写字母,则 $text 匹配精确的单词。
变音敏感度和词干
$diacriticSensitive: true启用区分变音符号 () 后,如果后缀词干包含变音符号,则$text 会匹配精确的单词。
不区分大小写。
启用区分大小写
指定 $caseSensitive: true 可在文本索引不区分大小写时启用区分大小写功能。
区分大小写的流程
当 $caseSensitive: true 且文本索引不区分大小写时,$text:
查询文本索引是否存在不区分大小写和不区分变音符号的匹配项。
筛选结果以仅返回与指定大小写匹配的文档。
当 $caseSensitive: true 且后缀词干包含大写字母时,$text 匹配精确的单词。
启用 $caseSensitive: true 可能会降低性能。
不区分变音符号
启用区分变音符号
指定 $diacriticSensitive: true 可启用3 版本文本索引区分变音符号的功能。
早期的文本索引版本始终区分变音符号,因此 $diacriticSensitive 不起作用。
区分变音符号的搜索过程
对于 3 版本的文本索引和 $diacriticSensitive: true、$text:
查询不区分变音符号的文本索引。
筛选结果以仅返回与指定术语中的变音符号匹配的文档。
启用 $diacriticSensitive: true 可能会降低性能。
对于早期的文本索引版本,$diacriticSensitive: true 会查询已经区分变音符号的文本索引。
当 $diacriticSensitive: true 且后缀词干包含变音符号时,$text 会匹配精确的单词。
提示
文本分数
$text 操作符将为每个结果文档分配分数。该分数表示文档与给定查询的相关性。该分数可以是 sort() 方法规范的一部分,也可以是投影表达式的一部分。{ $meta: "textScore" } 表达式提供了有关 $text 操作的处理信息。有关访问投影或排序分数的详细信息,请参见 $meta 投影操作符。
示例
以下示例使用articles 集合,其版本 3文本索引位于subject :
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 字符串对每个术语执行逻辑 OR。 MongoDB返回包含任何术语的文档。
此示例指定了三个以空格分隔的术语:
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 }
搜索精确字符串
对引号进行转义以匹配精确的多单词字符串。
此示例与精确的字符串 coffee shop 匹配:
db.articles.find( { $text: { $search: "\"coffee shop\"" } } )
此操作会返回包含字符串 coffee shop 的文档:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
此示例对两个精确字符串执行逻辑 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 } ]
提示
排除包含术语的文档
-在术语可排除包含该术语的文档。
此示例匹配包含 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 }
查询另一种语言
使用 $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 }
您也可以按名称指定语言,例如spanish 。有关支持的语言,请参阅自管理部署上的文本搜索语言。
提示
不区分大小写和变音符号
$text 默认为文本索引的不区分大小写和变音符号。3 版本的文本索引对带变音符号的拉丁字符和西里尔字母等非拉丁字母不区分变音符号和大小写。请参阅文本“索引不区分大小写”和文本“索引不区分变音符号”。
此示例执行不区分大小写和变音符号的查询:
db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } )
使用版本 3 文本索引,匹配:
{ "_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 }
早期的文本索引版本无法匹配任何文档。
区分大小写
使用 $caseSensitive: true 启用区分大小写。这可能会降低性能。
区分大小写的术语搜索
此示例对 Coffee 执行区分大小写的查询:
db.articles.find( { $text: { $search: "Coffee", $caseSensitive: true } } )
这仅匹配:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
区分大小写的精确字符串搜索
此示例对精确的多单词字符串执行区分大小写的查询:
db.articles.find( { $text: { $search: "\"Café Con Leche\"", $caseSensitive: true } } )
这仅匹配:
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 }
区分大小写的否定词搜索
-您可以使用案例大小写。
此示例对包含 Coffee 但不包含 shop 的文档执行区分大小写的查询(词干处理版本):
db.articles.find( { $text: { $search: "Coffee -shop", $caseSensitive: true } } )
这匹配:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg" }
区分变音符号
通过使用3 的$diacriticSensitive: true 版本文本索引启用区分变音符号。这可能会降低性能。
区分变音符号的术语搜索
此示例对 CAFÉ(词干提取版本)执行区分变音符号的查询:
db.articles.find( { $text: { $search: "CAFÉ", $diacriticSensitive: true } } )
这仅匹配:
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc" }
区分变音符号的否定词搜索
您可以使用区分变音符号与否定词(前缀为 - 的词)。
此示例对包含 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 namedscorefor the expression and thesort()uses the field namedignoredName.db.articles.find( { $text: { $search: "cake" } } , { score: { $meta: "textScore" } } ).sort( { ignoredName: { $meta: "textScore" } } )
提示
返回前 2 个匹配文档
此示例查询 coffee,按分数降序排序,并将结果限制为前两个文档:
db.articles.find( { $text: { $search: "coffee" } }, { score: { $meta: "textScore" } } ).sort( { score: { $meta: "textScore" } } ).limit(2)
提示
将 $text 与其他查询和排序操作相结合
此示例匹配 author 为 "xyz" 且 subject 包含 coffee 或 bake 的文档。它按 date 升序排序,然后相关性分数降序排序:
db.articles.find( { author: "xyz", $text: { $search: "coffee bake" } }, { score: { $meta: "textScore" } } ).sort( { date: 1, score: { $meta: "textScore" } } )