首页 > 代码库 > [Elasticsearch] 部分匹配 (二) - 通配符及正则表达式查询
[Elasticsearch] 部分匹配 (二) - 通配符及正则表达式查询
通配符和正则表达式查询
wildcard查询和prefix查询类似,也是一个基于词条的低级别查询。但是它能够让你指定一个模式(Pattern),而不是一个前缀(Prefix)。它使用标准的shell通配符:?用来匹配任意字符,*用来匹配零个或者多个字符。
以下查询能够匹配包含W1F 7HW和W2F 8HW的文档:
GET /my_index/address/_search { "query": { "wildcard": { "postcode": "W?F*HW" } } }
假设现在你想匹配在W地域(Area)的所有邮政编码。使用前缀匹配时,以WC开头的邮政编码也会被匹配,在使用通配符查询时也会遇到类似的问题。我们只想匹配以W开头,紧跟着数字的邮政编码。使用regexp查询能够让你写下更复杂的模式:
GET /my_index/address/_search { "query": { "regexp": { "postcode": "W[0-9].+" } } }
这个正则表达式的规定了词条需要以W开头,紧跟着一个0到9的数字,然后是一个或者多个其它字符。
wildcard和regexp查询的工作方式和prefix查询完全一样。它们也需要遍历倒排索引中的词条列表来找到所有的匹配词条,然后逐个词条地收集对应的文档ID。它们和prefix查询的唯一区别在于它们能够支持更加复杂的模式。
这也意味着使用它们存在相同的风险。对一个含有很多不同词条的字段运行这类查询是非常消耗资源的。避免使用一个以通配符开头的模式(比如,*foo或者正则表达式: .*foo)。
尽管对于前缀匹配,可以在索引期间准备你的数据让它更加高效,通配符和正则表达式匹配只能在查询期间被完成。虽然使用场景有限,但是这些查询也有它们的用武之地。
注意
prefix,wildcard以及regexp查询基于词条进行操作。如果你在一个analyzed字段上使用了它们,它们会检查字段中的每个词条,而不是整个字段。
比如,假设我们的title字段中含有"Quick brown fox",它会产生词条quick,brown和fox。
这个查询能够匹配:
{ "regexp": { "title": "br.*" }}
而不会匹配:
{ "regexp": { "title": "Qu.*" }} { "regexp": { "title": "quick br*" }}
[Elasticsearch] 部分匹配 (二) - 通配符及正则表达式查询