Elasticsearch查询空email字段无结果的原因排查
问题
尝试从Elasticsearch索引中获取email字段为空的文档,执行以下term查询时返回0条结果:
"query": { "term": { "email": "" } }
查询响应结果:
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 0, "relation" : "eq" }, "max_score" : null, "hits" : [ ] } }
但针对id字段执行term查询:
{ "query": { "term": { "id": "1234" } } }
能获取到email字段为空的文档:
"_source" : { "id" : "1234", "email" : "", }
索引映射配置:
{ "mappings": { "_doc": { "dynamic": "false", "properties": { "email": { "type": "text", "analyzer": "email_analyzer" }, "id": { "type": "keyword" } } } } }
请问导致该查询异常的原因是什么?
原因分析
- text类型字段的分词特性:
email字段是text类型且使用自定义email_analyzer分词器。当字段值为空字符串时,Elasticsearch的分词器会忽略这类空值,不会为其生成任何倒排索引条目。而term查询是直接匹配倒排索引中的精确词条,没有对应词条自然返回0结果。 - keyword类型的存储差异:
id字段是keyword类型,这类字段会原样存储所有值(包括空字符串)到倒排索引中,所以term查询能精确匹配到目标文档。 - 空值的索引逻辑:
text类型字段的空字符串不会被纳入索引,即使_source中保留了这个空值,倒排索引里也没有对应的匹配词条,导致term查询无法命中。
内容的提问来源于stack exchange,提问作者Claudiu Stoica
相关产品推荐
相关产品推荐

