Elasticsearch含特殊字符字段查询需求及配置求助
Elasticsearch支持特殊字符查询的解决方案
我需要在Elasticsearch中实现包含特殊字符的查询,已创建带有自定义分析器的索引,索引配置和测试数据如下:
{ "settings": { "analysis": { "filter": { "specialCharFilter": { "type": "ngram", "min_gram": 2, "max_gram": 30 } }, "analyzer": { "specialChar": { "type": "custom", "tokenizer": "custom_tokenizer", "filter": [ "lowercase", "specialCharFilter" ] } }, "tokenizer": { "custom_tokenizer": { "type": "ngram", "min_gram": 2, "max_gram": 30, "token_chars": [ "letter", "digit", "symbol", "punctuation" ] } } }, "index.max_ngram_diff": 30 }, "mappings": { "properties": { "partyName": { "type": "keyword", "analyzer": "specialChar", "search_analyzer": "standard" } } } }
测试数据:
[ { "partyName": "FLYJAC LOGISTICS PVT LTD-TPTBLR ." }, { "partyName": "L&T GEOSTRUCTURE PRIVATE LIMITED" } ]
执行查询{"query": {"match": {"partyName": "L&T"}}}时,期望返回包含L&T GEOSTRUCTURE PRIVATE LIMITED的结果,但当前配置无法实现,以下是修正方案:
问题根源
partyName字段设置为keyword类型,该类型默认不执行分词分析,即使指定了analyzer也无法生效,导致自定义的specialChar分析器完全没作用在索引过程中;- 查询时使用的
search_analyzer是standard,这个分析器会把查询词L&T拆分为L和T两个独立token,无法匹配到包含L&T的原始内容。
修正后的索引配置
将partyName改为text类型(只有text类型会应用指定的分析器做分词索引),同时让查询时使用和索引一致的specialChar分析器:
{ "settings": { "analysis": { "filter": { "specialCharFilter": { "type": "ngram", "min_gram": 2, "max_gram": 30 } }, "analyzer": { "specialChar": { "type": "custom", "tokenizer": "custom_tokenizer", "filter": [ "lowercase", "specialCharFilter" ] } }, "tokenizer": { "custom_tokenizer": { "type": "ngram", "min_gram": 2, "max_gram": 30, "token_chars": [ "letter", "digit", "symbol", "punctuation" ] } } }, "index.max_ngram_diff": 30 }, "mappings": { "properties": { "partyName": { "type": "text", "analyzer": "specialChar", "search_analyzer": "specialChar" // 可选,去掉则默认使用analyzer的配置 } } } }
验证查询
重新创建索引并导入测试数据后,执行原查询:
{"query": {"match": {"partyName": "L&T"}}}
即可得到期望结果:
{ "hits": { "total": { "value": 1, "relation": "eq" }, "hits": [ { "_source": { "partyName": "L&T GEOSTRUCTURE PRIVATE LIMITED" } } ] } }
补充:多字段兼容精确+模糊查询
如果需要同时支持精确匹配和包含特殊字符的模糊查询,可以用多字段配置,保留keyword类型用于精确匹配,text类型用于模糊查询:
"partyName": { "type": "text", "analyzer": "specialChar", "fields": { "keyword": { "type": "keyword" } } }
此时精确查询用partyName.keyword字段,模糊查询直接用partyName字段即可。
内容的提问来源于stack exchange,提问作者Hanu Skumar
相关产品推荐
相关产品推荐

