定义
regex
regex
将query
字段解释为正则表达式。regex
是术语级操作符,因而不会分析query
字段。注意
regex
操作符可用的正则表达式语言为 PCRE 库的有限子集。有关详细信息,请参阅 RegExp 类 文档。
语法
regex
通过以下语法实现:
1 { 2 $search: { 3 "index": <index name>, // optional, defaults to "default" 4 "regex": { 5 "query": "<search-string>", 6 "path": "<field-to-search>", 7 "allowAnalyzedField": <boolean>, 8 "score": <options> 9 } 10 } 11 }
选项
regex
使用以下词条来构造查询:
字段 | 类型 | 说明 | 必要性 | 默认 |
---|---|---|---|---|
| 字符串或字符串数组 | 要搜索的一个或多个字符串。 | 是 | |
| 字符串或字符串数组 | 要搜索的一个或多个带索引字段。您还可以指定通配符路径进行搜索。 | 是 | |
| 布尔 | 如果针对分析字段运行查询,则必须设置为 | no |
|
| 对象 | 分配给匹配搜索词结果的分数。选项包括:
| no |
行为
regex
为词级运算符,因而不会分析 query
字段。正则表达式搜索与关键字分析器配合得很好,因为它一次只能索引一个单词的字段。要进行区分大小写的搜索,请勿使用默认分析器(标准分析器),因为 standard
分析器会小写所有术语。请改为指定其他分析器。
通过将 allowAnalyzedField
选项设置为 true
,可以使用 regex
运算符对分析后的字段执行搜索,但可能会出现意外结果。
Lucene 正则表达式行为
Atlas Search regex
操作符使用 Lucene 正则表达式引擎,它不同于 Perl 兼容正则表达式。
保留字符
在正则表达式中使用时,以下字符保留为操作符:
. ? + * | { } [ ] ( ) < > " \ @ #
要在匹配表达式中按字面意思使用任何上述字符,请在其前面添加\
字符。
例子
who\?
匹配 "who?"
在 mongosh
中或驱动程序中使用转义字符时,必须在要转义的字符前使用双反斜杠。
例子
要创建一个通配符表达式来搜索聚合管道中包含字面星号的任何字符串,请使用以下表达式:
"*\\**"
第一个和最后一个星号作为通配符,可匹配任何字符,而 \\*
则匹配文字星号。
注意
使用以下表达式对文本反斜杠进行转义:
"*\\\*"
支持的操作符
Operator | 说明 | 例子 |
---|---|---|
| 匹配任何字符。 |
|
| 前面的字符是可选的,如果其出现次数不超过一次,则匹配。 |
|
| 如果前面的字符出现一次或多次,则匹配。 |
|
| 如果前面的字符出现任意次数,则匹配。 |
|
|
|
|
| 如果前面的字符恰好出现 <number> 次,则匹配。 |
|
| 括号内的字符在匹配时被视为一个单元。 |
|
| 与方括号内的任何字符匹配。 在开头添加 在方括号内, | [xyz] matches "x", "y", and "z"[^abc] matches any character except "a", "b", or "c"[a-d] matches "a", "b", "c", or "d"[0-9] matches any numeric character from 0 through 9 |
| 匹配数值范围。 |
|
| 空语言操作符。 |
|
不支持的运算符
regex
不支持锚点操作符。示例,不支持以下操作符:
^
,用于匹配行首。$
,它与行尾相匹配。
要匹配一个术语,正则表达式必须匹配整个字符串。
示例
以下示例将 sample_mflix
数据库的 movies
集合与使用关键字分析器的自定义索引定义结合使用。如果集群有示例数据集,则可以在 movies
集合上创建 Atlas Search 索引,并在集群上运行示例查询。
索引定义
以下索引定义使用关键字分析器对 movies
集合中的 title
字段进行索引:
1 { 2 "mappings": { 3 "fields": { 4 "title": { 5 "analyzer": "lucene.keyword", 6 "type": "string" 7 }, 8 "genres": { 9 "type": "token" 10 } 11 } 12 } 13 }
以下示例在所有 title
字段中搜索以单词 Seattle
结尾的电影标题。(.*)
正则表达式匹配任意数量的字符。
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "regex": { 5 "path": "title", 6 "query": "(.*) Seattle" 7 } 8 } 9 }, 10 { 11 $project: { 12 "_id": 0, 13 "title": 1 14 } 15 } 16 ])
{ "title" : "Sleepless in Seattle" } { "title" : "Battle in Seattle" }
以下示例使用正则表达式 [0-9]{2} (.){4}s
查找以 2 位数字开头,后跟 1 个空格,并以最后 1 个字母为 s
的 5 个字母单词结尾的电影标题。
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "regex": { 5 "path": "title", 6 "query": "[0-9]{2} (.){4}s" 7 } 8 } 9 }, 10 { 11 $project: { 12 "_id": 0, 13 "title": 1 14 } 15 } 16 ])
{ "title" : "20 Dates" } { "title" : "25 Watts" } { "title" : "21 Grams" } { "title" : "13 Lakes" } { "title" : "18 Meals" } { "title" : "17 Girls" } { "title" : "16 Acres" } { "title" : "26 Years" } { "title" : "99 Homes" } { "title" : "45 Years" }
以下示例使用正则表达式 .*
查找在 title
中任何位置包含术语 summer
的电影标题,并返回每个类别中符合条件的电影数量。
1 db.movies.aggregate([ 2 { 3 "$searchMeta": { 4 "facet": { 5 "operator": { 6 "regex": { 7 "path": "title", 8 "query": ".*summer.*" 9 } 10 }, 11 "facets": { 12 "genresFacet": { 13 "type": "string", 14 "path": "genres" 15 } 16 } 17 } 18 } 19 } 20 ])
[ { count: { lowerBound: Long('6') }, facet: { genresFacet: { buckets: [ { _id: 'Comedy', count: Long('5') }, { _id: 'Fantasy', count: Long('3') }, { _id: 'Romance', count: Long('3') }, { _id: 'Drama', count: Long('2') }, { _id: 'Horror', count: Long('1') }, { _id: 'Mystery', count: Long('1') } ] } } } ]