Elasticsearch 中的查询(Query)与过滤(Filter):核心区别与应用场景
在 Elasticsearch 中,查询(Query)和过滤(Filter)是两种核心的数据筛选机制,虽然都能实现结果筛选,但在用途、性能和实现方式上有本质区别。理解二者的差异是优化查询性能和相关性的关键。
核心区别
| 维度 | 查询(Query) | 过滤(Filter) |
|---|---|---|
| 核心目标 | 筛选匹配的文档,并计算相关性得分(_score) | 仅筛选匹配的文档,不计算得分 |
| 性能特点 | 消耗 CPU 资源(需计算得分),无缓存 | 不消耗额外 CPU,结果可被缓存(Filter Cache) |
| 适用场景 | 全文检索、相关性排序(如 “搜索关键词”) | 精确匹配、范围筛选(如 “价格> 100”“状态 = 激活”) |
查询(Query):注重相关性
查询操作不仅会筛选出符合条件的文档,还会根据文档与查询条件的匹配程度计算相关性得分(_score),得分越高,文档与查询的相关性越强。
常用查询类型
- 全文查询:
match、match_phrase(用于文本字段,会分词)。 - 术语查询:
term、terms(用于精确匹配,如关键词、数字)。 - 复合查询:
bool、dis_max(组合多个查询条件)。
示例:匹配 “elasticsearch 教程” 并计算得分
1 | GET books/_search |
响应中包含 _score 字段,反映文档与查询的相关性:
1 | { |
过滤(Filter):注重高效筛选
过滤操作仅根据条件筛选文档,不计算得分,结果可被缓存(Filter Cache),适合频繁执行的固定条件(如状态、时间范围)。
常用过滤场景
- 范围筛选(
range):如 “价格 between 100 and 200”。 - 精确匹配(
term):如 “category = 手机”。 - 存在性检查(
exists):如 “field: price”(筛选有价格字段的文档)。
示例:筛选价格 > 100 且状态为 “在售” 的商品
1 | GET products/_search |
- 性能优势:过滤条件的结果会被缓存,后续相同查询可直接复用,大幅提升效率。
- 无得分:响应中
_score均为 0(或 1.0,不影响排序)。
何时使用查询 vs 过滤?
- 使用查询(Query)的场景:
- 需要根据相关性排序(如全文搜索、推荐系统)。
- 条件涉及文本分词匹配(如 “标题包含 Elasticsearch”)。
- 使用过滤(Filter)的场景:
- 条件是精确匹配或范围筛选(如 “日期在近 7 天内”“类型 = 视频”)。
- 条件频繁重复使用(如 “仅显示已激活的用户”),可利用缓存提升性能。
组合使用:查询 + 过滤
实际场景中,常结合两者优势:用过滤筛选基础条件(高效),用查询计算相关性(精准排序)。
示例:搜索 “手机” 且价格 < 5000 的商品,按相关性排序
1 | GET products/_search |
- 执行逻辑:先通过
filter筛选价格 < 5000 的商品,再在结果中通过must计算 “手机” 的相关性得分。 - 性能优化:过滤条件优先执行并缓存,减少后续查询的处理数据量。
性能对比与最佳实践
- 性能:过滤 > 查询(因缓存和无得分计算)。
- 缓存:
- 过滤结果默认缓存(可通过
index.queries.cache.enabled配置)。 - 查询结果不缓存(得分可能随索引更新变化)。
- 过滤结果默认缓存(可通过
- 最佳实践:
- 固定条件(如状态、类型)用过滤,动态文本条件用查询。
- 复杂查询优先通过过滤缩小范围,再进行相关性计算