Elasticsearch无法按单个词项搜索的问题解决咨询
Elasticsearch title字段无法按单个词项搜索的解决方法
问题背景
现有Elasticsearch环境信息如下:
1. 目标文档
{"_index" : "trigger","_type" : "_doc","_id" : "urn:trigger:(urn:analyticsplatform:uc4):acxiom_au_attr.done","_version" : 45,"_seq_no" : 420508,"_primary_term" : 20,"found" : true,"_source" : {"_boostScoreFactor" : 1.0,"type" : "trigger","title" : "acxiom_au_attr.done",}}
2. title字段映射
"title" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }
3. 索引设置
{"trigger" : {"settings" : {"index" : {"routing" : {"allocation" : {"total_shards_per_node" : "2"}},"number_of_shards" : "1","provided_name" : "trigger","creation_date" : "1668526304683","unassigned" : {"node_left" : {"delayed_timeout" : "15m"}},"analysis" : {"filter" : {"discovery_stemmer" : {"type" : "stemmer","language" : "porter2"},"discovery_stemmer_possessive" : {"type" : "stemmer","language" : "minimal_english"},"discovery_synonym_abbr" : {"type" : "synonym_graph","synonyms" : ["BN => browse node"]}},"char_filter" : {"discovery_charfilter" : {"type" : "mapping","mappings" : [".=>|","_=>|"]}},"normalizer" : {"lowercase" : {"filter" : ["lowercase"],"type" : "custom","char_filter" : [ ]}},"analyzer" : {"discovery_index_analyzer" : {"filter" : ["lowercase","discovery_synonym_abbr"],"char_filter" : ["discovery_charfilter"],"type" : "custom","tokenizer" : "standard"}}},"number_of_replicas" : "2","uuid" : "oMzEq9L_Sum8A5ikwLyCdQ","version" : {"created" : "135238227"}}}}
4. 预期分词结果
使用discovery_index_analyzer分析acxiom_au_attr.done得到的词项:
{"tokens" : [{"token" : "acxiom","start_offset" : 0,"end_offset" : 6,"type" : "<ALPHANUM>","position" : 0},{"token" : "au","start_offset" : 7,"end_offset" : 9,"type" : "<ALPHANUM>","position" : 1},{"token" : "attr","start_offset" : 10,"end_offset" : 14,"type" : "<ALPHANUM>","position" : 2},{"token" : "done","start_offset" : 19,"end_offset" : 23,"type" : "<ALPHANUM>","position" : 4}]}
问题现象
- 执行单个词项查询时无结果返回:
GET trigger/_search {"query": {"match": {"title": "acxiom"}}}
- 使用完整title值查询时可正常返回目标文档:
GET trigger/_search {"query": {"match": {"title": "acxiom_au_attr.done"}}}
问题原因
title字段未明确指定使用自定义的discovery_index_analyzer作为索引和查询分析器,导致:
- 索引时字段使用Elasticsearch默认的
standard分析器,该分析器不会将_和.视为分隔符,因此acxiom_au_attr.done会被拆分为acxiom、au、attr.done三个词项,与预期的分词结果不符; - 查询时默认使用的分析器与索引时不一致,进一步导致词项无法匹配。
解决方案
方案1:修改字段映射并重新索引数据(推荐)
由于已创建的text字段无法直接修改分析器,需重新创建索引并迁移数据:
- 创建新索引(例如
trigger_new),配置正确的分析器及字段映射:
PUT trigger_new { "settings": { "index": { "routing": { "allocation": { "total_shards_per_node": "2" } }, "number_of_shards": "1", "unassigned": { "node_left": { "delayed_timeout": "15m" } }, "analysis": { "filter": { "discovery_stemmer": { "type": "stemmer", "language": "porter2" }, "discovery_stemmer_possessive": { "type": "stemmer", "language": "minimal_english" }, "discovery_synonym_abbr": { "type": "synonym_graph", "synonyms": ["BN => browse node"] } }, "char_filter": { "discovery_charfilter": { "type": "mapping", "mappings": [".=>|", "_=>|"] } }, "normalizer": { "lowercase": { "filter": ["lowercase"], "type": "custom", "char_filter": [] } }, "analyzer": { "discovery_index_analyzer": { "filter": ["lowercase", "discovery_synonym_abbr"], "char_filter": ["discovery_charfilter"], "type": "custom", "tokenizer": "standard" } } }, "number_of_replicas": "2" } }, "mappings": { "_doc": { "properties": { "title": { "type": "text", "analyzer": "discovery_index_analyzer", "search_analyzer": "discovery_index_analyzer", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "_boostScoreFactor": { "type": "float" }, "type": { "type": "text" } } } } }
- 将原索引数据迁移至新索引:
POST _reindex { "source": { "index": "trigger" }, "dest": { "index": "trigger_new" } }
- 测试单个词项查询:
GET trigger_new/_search { "query": { "match": { "title": "acxiom" } } }
方案2:查询时指定分析器(临时解决)
如果暂时无法重新索引,可在查询时强制指定使用discovery_index_analyzer,确保查询词的分词逻辑与预期一致:
GET trigger/_search { "query": { "match": { "title": { "query": "acxiom", "analyzer": "discovery_index_analyzer" } } } }
内容的提问来源于stack exchange,提问作者Jacky Guo
相关产品推荐
相关产品推荐

