es中常规的根据字段查询时走什么索引(说明:「常规的根据字段查询」不包含分词查询)
在Elasticsearch中,“常规的根据字段查询”且不涉及分词的查询(如精确匹配、范围查询),主要依赖以下索引机制:
一、核心索引类型及适用场景
字段类型 | 索引结构 | 典型查询方式 | 应用场景 |
---|---|---|---|
keyword | 倒排索引(未分词) | term 、terms 、exists | 订单ID、状态码、标签等精确匹配 |
数值/日期 | BKD树索引(多维空间划分) | range 、> 、< 、聚合 | 价格区间、时间范围筛选 |
boolean | 倒排索引(二元值) | term | 状态标记(如is_active=true ) |
ip | 特殊编码倒排索引 | term 、prefix 、cidr | IP地址过滤与网段查询 |
注:所有精确匹配类查询均跳过文本分析(Analysis)环节,直接基于原始值检索。
二、查询执行流程(以keyword
为例)
- 值标准化
查询值"ES2025"
→ 按字段类型处理(如keyword
保持原值); - 倒排索引检索
定位词项词典(Term Dictionary)中的"ES2025"
,获取其倒排列表(Posting List); - 结果返回
直接返回匹配文档ID集合,无相关性评分(因filter
上下文不计算得分)。
三、性能优化关键点
-
索引设计
keyword
替代text
:对无需分词的字段(如ID、枚举值)显式定义为keyword
,避免无效分词开销;- 禁用
norms
:对仅用于过滤的keyword
字段设置"norms": false
,减少磁盘占用;
-
查询策略
- 使用
filter
上下文:利用位图(BitSet)缓存结果,重复查询速度提升100倍+;"bool": {"filter": [ // 无评分计算{"term": {"status": "published"}},{"range": {"price": {"gte": 100}}}] }
- 分片路由优化:对高频过滤字段(如
user_id
)设置routing_path
,使查询集中到特定分片;
- 使用
-
存储压缩
doc_values
启用:默认开启,支持对keyword
/数值字段高效聚合、排序;- 列式存储优化:BKD树索引对数值范围查询采用数据压缩,减少I/O压力。
四、注意事项
text
字段的精确匹配陷阱:
即使使用term
查询text
字段,ES仍会先分词再匹配(如"Quick Fox"
被拆分为["quick","fox"]
),导致无法精确命中 → 必须改用.keyword
子字段。- 高基数
keyword
字段:
值基数过高(如user_id
)时,需监控堆内存,避免Fielddata膨胀。
五、总结
常规非分词字段查询的核心索引机制:
- 精确匹配 →
keyword
类型倒排索引(值完全匹配); - 范围查询 → 数值/日期类型BKD树索引(高效空间划分);
优化本质:跳过文本分析、利用列式存储与缓存,实现亚毫秒级响应。