Elasticsearch multi_match bool_prefix查询结合fuzziness容错问题咨询
共性配置优化
你当前查询的fields列表中手动列出了所有._2gram、._3gram子字段,属于冗余配置,search_as_you_type类型的字段在使用bool_prefix类型查询时,ES会自动关联这些子字段,直接填写根字段名即可,能降低查询解析开销。另外questions.tags字段不是search_as_you_type类型,对应的._2gram、._3gram字段不存在,ES会自动忽略这部分配置,建议删除。
问题3:无拼写错误时添加fuzziness返回更多结果的原因
bool_prefix类型的multi_match查询,fuzziness配置仅对除最后一个词之外的所有词生效,最后一个词始终执行前缀匹配,不会应用模糊规则。添加fuzziness后,前面的所有词都允许命中和原词编辑距离符合AUTO规则的其他词,哪怕原词拼写完全正确,也会额外命中大量模糊匹配的文档,所以返回结果数量会增加。
问题1:单单词查询的模糊容错实现方案
单单词查询时,这个唯一的查询词属于bool_prefix规则里的「最后一个词」,fuzziness配置不会生效,只会做前缀匹配,所以拼写错误的triangld无法匹配到正确的triangle。
你可以在后端判断查询词数量,单单词查询时用bool组合查询保留输入即搜能力的同时叠加模糊匹配能力,示例如下:
{ "query": { "bool": { "should": [ // 保留原有bool_prefix前缀匹配能力,权重最高 { "multi_match": { "query": "triangld", "type": "bool_prefix", "fields": ["title", "description", "questions.content", "questions.tags"], "boost": 10 } }, // 叠加全字段模糊匹配,命中拼写错误场景,权重次之 { "multi_match": { "query": "triangld", "fuzziness": "AUTO", "fields": ["title", "description", "questions.content", "questions.tags"], "boost": 5 } } ], "minimum_should_match": 1 } } }
该方案完全保留输入即搜的前缀匹配特性,同时能覆盖拼写错误的模糊匹配场景。
问题2:短语最后一个单词拼写错误的排序异常解决方案
排序异常的核心原因是:多词查询时最后一个词不应用fuzziness规则,仅做前缀匹配。比如搜索right triangdd时,triangdd的前缀匹配不到任何和triangle相关的内容,仅前面的right生效,所以只命中right的文档会排在最前。
你可以在后端判断为多词查询时,额外加一层「所有词都做模糊匹配」的子查询拉高相关结果的权重,示例如下:
{ "query": { "bool": { "should": [ // 保留原有bool_prefix查询,优先级最高 { "multi_match": { "query": "right triangdd", "type": "bool_prefix", "fields": ["title", "description", "questions.content", "questions.tags"], "boost": 10 } }, // 新增全词模糊匹配子句,同时命中所有词的结果加权 { "multi_match": { "query": "right triangdd", "fuzziness": "AUTO", "operator": "and", "fields": ["title", "description", "questions.content", "questions.tags"], "boost": 8 } } ], "minimum_should_match": 1 } } }
这样同时匹配两个词(含模糊匹配)的文档权重会高于仅匹配单个词的文档,自然会排在前列,解决排序异常问题。
问题4:是否需要调整分词器配置
现有配置不需要做大的调整:
- search_as_you_type字段的
max_shingle_size设为3符合绝大多数输入即搜的场景,不需要修改 - 如果
questions.tags字段也需要支持输入即搜能力,可以把它的类型也改成search_as_you_type,否则直接保留现有配置即可 - 如果有中英文混合查询需求,可以给search_as_you_type字段加
"analyzer": "ik_max_word"配置优化中文分词效果,纯英文场景用默认的standard分词器就足够
内容的提问来源于stack exchange,提问作者Константин Манойло

