为Elasticsearch自定义分析器添加大小写不敏感精确匹配搜索
问题描述
现有Elasticsearch 7.16版本的索引配置如下:
{ "entities": { "mappings": { "properties": { "content": { "type": "text", "analyzer": "stop_delimiter_stemmer_analyzer" } } } } }
自定义分析器stop_delimiter_stemmer_analyzer的配置:
"analysis": { "analyzer": { "stop_delimiter_stemmer_analyzer": { "tokenizer": "whitespace", "filter": [ "word_delimiter_graph", "german_stemmer", "english_stemmer", "french_stemmer", "italian_stemmer", "multi_language_stopwords" ] } }, "filter": { "german_stemmer": { "type": "stemmer", "name": "light_german" }, "english_stemmer": { "type": "stemmer", "name": "english" }, "french_stemmer": { "type": "stemmer", "name": "light_french" }, "italian_stemmer": { "type": "stemmer", "name": "light_italian" }, "multi_language_stopwords": { "type": "stop", "stopwords": [ "_english_", "_french_", "_italian_", "_dutch_" ] } } }
当前问题:使用match查询搜索"Preuve à futur"时,目标结果排在首位;但搜索小写的"preuve à futur"时,该结果排名靠后。需要实现大小写不敏感的精确匹配结果始终排在首位。
解决方案
方法一:添加大小写不敏感的精确匹配子字段(推荐)
通过给content字段添加归一化的keyword子字段,实现大小写无关的精确匹配,并通过权重提升让这类结果优先排名。
1. 定义小写归一器
在索引的analysis配置中新增归一器:
"analysis": { // 保留原有analyzer、filter配置 "normalizer": { "lowercase_normalizer": { "type": "custom", "filter": ["lowercase"] } } }
2. 更新字段映射
修改content字段的映射,添加raw子字段:
{ "entities": { "mappings": { "properties": { "content": { "type": "text", "analyzer": "stop_delimiter_stemmer_analyzer", "fields": { "raw": { "type": "keyword", "normalizer": "lowercase_normalizer" } } } } } } }
3. 重新索引数据
修改映射后需要重新索引现有数据,确保content.raw字段被正确填充。
4. 构造加权查询
使用bool查询同时包含精确匹配和原有全文查询,给精确匹配设置高权重:
{ "query": { "bool": { "should": [ { "term": { "content.raw": { "value": "preuve à futur", "boost": 10 } } }, { "match": { "content": "preuve à futur" } } ] } } }
无论搜索的是大写还是小写的目标文本,精确匹配的结果都会因高权重排在首位,同时不影响其他相关结果的返回。
方法二:修改自定义分析器添加小写过滤器(需评估影响)
如果不想新增字段,可以在分析器中加入lowercase过滤器统一分词大小写,再配合短语查询提升精确匹配权重。
1. 修改分析器配置
在过滤器列表最前端加入lowercase:
"analyzer": { "stop_delimiter_stemmer_analyzer": { "tokenizer": "whitespace", "filter": [ "lowercase", // 新增小写过滤器 "word_delimiter_graph", "german_stemmer", "english_stemmer", "french_stemmer", "italian_stemmer", "multi_language_stopwords" ] } }
2. 构造加权查询
使用bool查询包含短语匹配和全文查询,给短语匹配设置权重:
{ "query": { "bool": { "should": [ { "match_phrase": { "content": { "query": "preuve à futur", "boost": 5 } } }, { "match": { "content": "preuve à futur" } } ] } } }
注意:这种方法会改变原有分词逻辑,需要重新索引数据,可能影响其他查询行为,需谨慎评估后使用。
内容的提问来源于stack exchange,提问作者msln
相关产品推荐
相关产品推荐

