2019 年使用 Elasticsearch 7.4 的 Java 客户端时,查询有命中,hit.getHighlightFields() 却没有取得预期内容。相近的 Kibana 查询可以看到高亮,让问题一开始看起来像客户端读取错误。
当时改变了什么
排查发现 Java 查询构造器额外包含:
matchQueryBuilder.fuzziness(Fuzziness.AUTO);
移除该设置后,当时工程的高亮恢复。这是一次有效的观察,但不能据此断言 fuzziness 会普遍关闭高亮。
fuzziness 用于编辑距离容错,不是 wildcard 通配符;两者也都不等同于普通全文分词。参数改变后,查询语义已经变化,除了高亮,还应检查命中文档是否符合原需求。
先比较真正发出的请求
Kibana 和 Java 代码看起来都在搜索同一文本,最终 DSL 却可能不同。先保存客户端序列化后的请求,再对照字段、查询类型、fuzziness、highlight 配置和索引范围。
可从下面的简单请求建立对照,再按实际需求一次只增加一个条件:
GET /example_articles/_search
{
"query": {
"match": {
"title": "检索示例"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
title 应是与示例相符、可进行全文查询和高亮的字段;这不是对任意 mapping 都有效的配置。不同 highlighter 对查询的处理存在差异,应查对应版本说明。ES 7.4 高亮说明
区分服务端没有返回和客户端没有读到
先看原始响应中是否存在 highlight,再检查 Java 读取逻辑。若原始响应就没有,继续查查询、字段、分析器和高亮设置;若响应有而程序读不到,再查客户端解析、字段名和空值处理。
这次记录没有保存完整 DSL 与 mapping,因此没有足够证据确定唯一根因。可复用的方法是固定样本文档和配置做单变量对照,而不是把“删掉某行就恢复”提升为所有版本的规则。