ElasticSearch如何实现不同分词形式邮箱地址的统一检索
Elasticsearch 同时匹配两种分词格式邮箱的查询方法
问题场景
当前ES索引中message字段的邮箱地址存在两种索引形式:
- 被三重引号包裹的
"""email@address.com"""会被分词为1个独立token - 无包裹的
email@address.com会被现有分词规则拆为email、address.com两个位置连续的token
直接检索email@address.com时无法命中拆分token的文档,单独检索email会召回大量无关结果,已尝试的query_string、match+and、regexp三类查询均无法同时覆盖两种场景。
附无包裹邮箱的分词结果:
{ "tokens": [ { "token": "email", "start_offset": 0, "end_offset": 5, "type": "<ALPHANUM>", "position": 0 }, { "token": "address.com", "start_offset": 6, "end_offset": 17, "type": "<ALPHANUM>", "position": 1 } ] }
已尝试查询的失效原因
三类查询失效逻辑非常明确:
query_string+minimum_should_match:2、match+operator:and:要求查询拆分出的2个token必须同时命中,三重引号包裹的邮箱仅存1个完整token,不满足匹配条件直接漏召回regexp正则查询:ES的正则仅支持单个token内部的内容匹配,无法跨token匹配拆分后的两个连续分段,因此查不到无包裹的邮箱
可用方案
直接使用match_phrase短语匹配即可覆盖两种场景,不需要复杂组合:
GET _search { "query": { "match_phrase": { "message": "email@address.com" } } }
匹配逻辑
- 针对无包裹的拆分场景:查询文本
email@address.com分词后得到email(position 0)、address.com(position 1)两个token,match_phrase会要求两个token按顺序、位置连续出现,和索引中拆分后的token状态完全匹配,可正常命中 - 针对三重引号包裹的整token场景:短语匹配不会强制要求查询文本必须拆分为多token,只要字段中存在和查询文本一致的完整token,就会直接命中,不会漏召回
如果当前分词器会给三重引号包裹的邮箱前后保留引号字符,导致整token文本和查询文本不完全一致,可以加一个wildcard条件做兜底,兼容性更强:
GET _search { "query": { "bool": { "should": [ {"match_phrase": {"message": "email@address.com"}}, {"wildcard": {"message": "*email@address.com*"}} ], "minimum_should_match": 1 } } }
内容的提问来源于stack exchange,提问作者PepperoniPizza
相关产品推荐
相关产品推荐

