ElasticSearch wildcard查询含连字符内容高亮不完整问题咨询
问题原因
这是Elasticsearch的默认正常行为,本质是分词规则和查询匹配逻辑共同导致的:
- 你当前使用的
text类型字段默认采用标准分词器,会把连字符-识别为分词分隔符,test-input会被切分为test、input两个独立的词元存入索引 - 你用
test*做前缀查询时,仅匹配到了test这个词元,因此高亮模块只会对匹配到的test部分添加高亮标签
解决方案
方案1:新增不分词的子字段(无需调整原有分词逻辑,兼容性最好)
给content字段新增wildcard或keyword类型的子字段,专门用于模糊匹配和高亮,修改映射如下:
PUT testhighlight/_mapping/_doc { "properties": { "content": { "type": "text", "term_vector": "with_positions_offsets", "fields": { "raw": { "type": "wildcard" // 7.9+版本推荐用wildcard类型,低版本可以替换为keyword类型 } } } } }
修改查询请求,查询时同时命中分词字段和不分词字段,高亮指定使用content.raw的匹配结果:
GET testhighlight/_search { "query": { "bool": { "must": [ { "query_string": { "fields": [ "title", "content", "content.raw" ], "query": "test*" } } ] } }, "highlight": { "fields": { "content.raw": { "fragment_size": 250, "number_of_fragments": 5, "post_tags": [ "</span>" ], "pre_tags": [ "<span class=\"highlight-search\">" ] } } } }
方案2:自定义分词器,保留连字符作为词元的一部分
如果业务中连字符本身属于业务关键词的一部分,建议自定义分词器,修改标准分词器的分隔符规则,让test-input作为完整词元索引:
PUT testhighlight { "settings": { "analysis": { "analyzer": { "keep_hyphen_analyzer": { "tokenizer": "standard", "char_filter": [ "hyphen_replacement" ] } }, "char_filter": { "hyphen_replacement": { "type": "mapping", "mappings": [ "- => _" ] } } } }, "mappings": { "properties": { "title": { "type": "text", "term_vector": "with_positions_offsets" }, "content": { "type": "text", "term_vector": "with_positions_offsets", "analyzer": "keep_hyphen_analyzer" } } } }
重新索引数据后,原有查询逻辑无需修改即可实现完整高亮。
方案3:临时调整高亮逻辑(无需修改索引,适合快速验证)
如果不想修改索引结构,可以在查询中新增highlight_query,使用短语匹配规则覆盖高亮匹配逻辑:
GET testhighlight/_search { "query": { "bool": { "must": [ { "query_string": { "fields": [ "title", "content" ], "query": "test*" } } ] } }, "highlight": { "fields": { "content": { "boundary_max_scan": 10, "fragment_offset": 5, "fragment_size": 250, "type": "fvh", "number_of_fragments": 5, "order": "score", "boundary_scanner": "word", "post_tags": [ "</span>" ], "pre_tags": [ "<span class=\"highlight-search\">" ], "highlight_query": { "match_phrase_prefix": { "content": "test" } } } } } }
内容的提问来源于stack exchange,提问作者DenisNovac
相关产品推荐
相关产品推荐

