ElasticSearch无法匹配含下划线文件名的检索问题咨询
问题根因
检索不生效的核心是分词规则不匹配,直接触发点是你在查询中显式强制指定了standard分析器,完全没有适配文件名带下划线的场景:
standard是ES默认分析器,分词规则为:所有非字母、非数字的字符都会被识别为分词分隔符,切分完成后分隔符会被直接丢弃。下划线_属于非字母数字字符,会被直接当做切分标记处理,不会保留在分词结果中。- 你在
multi_match中硬编码了"analyzer": "standard",这个配置优先级最高,会直接覆盖字段mapping中预设的分词规则,无论索引时name、combined_folders字段用了什么分词逻辑,查询词都会被强制按standard规则切分,非常容易出现索引分词和查询分词不匹配的问题。没有特殊需求不要在查询语句中硬编码analyzer参数。 - 以你的测试场景为例:
- 文件名
file_example_ODS_100.ods如果按standard规则分词,会被拆成独立的token:file、example、ods、100、ods,根本不会保留file_example这类带下划线的连续片段;如果字段索引时用了其他不切分下划线的分析器(比如whitespace、keyword),索引中存储的token和standard切出来的查询token完全无法对应,直接匹配失败。 - 你传入的查询词
file_example会被standard切分成file、example两个独立token,再叠加你设置的operator: "AND"要求所有token在同字段命中,只要分词规则有一点偏差就会返回空结果。
- 文件名
解决方案
根据你的检索精度要求选对应方案即可:
- 方案1:追求精准匹配,支持文件名片段召回
给两个检索字段增加不分词的keyword子字段,同时走分词匹配和精确通配匹配,不需要改动原有分词逻辑,适合大多数文件检索场景(需要重建索引生效)。
首先调整字段mapping:
调整查询语句,去掉硬编码的standard分析器配置,增加keyword字段的通配匹配规则:{ "mappings": { "properties": { "name": { "type": "text", "fields": { "raw": { "type": "keyword" } } }, "combined_folders": { "type": "text", "fields": { "raw": { "type": "keyword" } } } } } }{ "bool": { "should": [ { "multi_match": { "fields": [ "name^2", "combined_folders^2" ], "query": "你的查询词", "max_expansions": 50, "fuzziness": "2", "lenient": true, "prefix_length": 1, "operator": "AND", "minimum_should_match": "20%" } }, { "wildcard": { "name.raw": { "value": "*你的查询词*", "boost": 3 } } }, { "wildcard": { "combined_folders.raw": { "value": "*你的查询词*", "boost": 3 } } } ], "minimum_should_match" : 1 } } - 方案2:需要分词召回,同时保留下划线为有效字符
自定义文件名专用分析器,将下划线排除在分词分隔符之外,让file_example这类带下划线的片段能作为完整token被索引(需要重建索引生效)。
索引配置示例:
配置后上述文件名会被拆分为{ "settings": { "analysis": { "tokenizer": { "filename_tokenizer": { "type": "pattern", "pattern": "[\\s/\\\\.\\-\\(\\)\\[\\]{}!@#$%^&*+=]+", "lowercase": true } }, "analyzer": { "filename_analyzer": { "tokenizer": "filename_tokenizer", "filter": ["lowercase"] } } } }, "mappings": { "properties": { "name": { "type": "text", "analyzer": "filename_analyzer" }, "combined_folders": { "type": "text", "analyzer": "filename_analyzer" } } } }file_example_ods_100、ods两个token,查询时去掉硬编码的analyzer参数即可直接命中file_example相关的查询词。 - 方案3:临时快速修复(不推荐生产环境使用)
如果暂时无法重建索引,可以直接把查询语句中"analyzer": "standard"配置删除,或者替换为"analyzer": "whitespace",按空格做分词切分,下划线不会被识别为分隔符。缺点是其他特殊字符(比如点、横杠、括号)也不会被切分,检索召回准确率会明显下降。
内容的提问来源于stack exchange,提问作者Stanislau Karaliou
相关产品推荐
相关产品推荐

