0%

查询和过滤

Elasticsearch 中的查询(Query)与过滤(Filter):核心区别与应用场景

在 Elasticsearch 中,查询(Query)和过滤(Filter)是两种核心的数据筛选机制,虽然都能实现结果筛选,但在用途、性能和实现方式上有本质区别。理解二者的差异是优化查询性能和相关性的关键。

核心区别

维度 查询(Query) 过滤(Filter)
核心目标 筛选匹配的文档,并计算相关性得分(_score) 仅筛选匹配的文档,不计算得分
性能特点 消耗 CPU 资源(需计算得分),无缓存 不消耗额外 CPU,结果可被缓存(Filter Cache)
适用场景 全文检索、相关性排序(如 “搜索关键词”) 精确匹配、范围筛选(如 “价格> 100”“状态 = 激活”)

查询(Query):注重相关性

查询操作不仅会筛选出符合条件的文档,还会根据文档与查询条件的匹配程度计算相关性得分_score),得分越高,文档与查询的相关性越强。

常用查询类型

  • 全文查询matchmatch_phrase(用于文本字段,会分词)。
  • 术语查询termterms(用于精确匹配,如关键词、数字)。
  • 复合查询booldis_max(组合多个查询条件)。

示例:匹配 “elasticsearch 教程” 并计算得分

1
2
3
4
5
6
7
8
GET books/_search
{
"query": {
"match": {
"title": "elasticsearch 教程" // 全文匹配,计算得分
}
}
}

响应中包含 _score 字段,反映文档与查询的相关性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"hits": {
"hits": [
{
"_score": 2.5, // 相关性得分
"_source": { "title": "Elasticsearch 实战教程" }
},
{
"_score": 1.8, // 得分较低,相关性较弱
"_source": { "title": "搜索引擎原理与 Elasticsearch 应用" }
}
]
}
}

过滤(Filter):注重高效筛选

过滤操作仅根据条件筛选文档,不计算得分,结果可被缓存(Filter Cache),适合频繁执行的固定条件(如状态、时间范围)。

常用过滤场景

  • 范围筛选(range):如 “价格 between 100 and 200”。
  • 精确匹配(term):如 “category = 手机”。
  • 存在性检查(exists):如 “field: price”(筛选有价格字段的文档)。

示例:筛选价格 > 100 且状态为 “在售” 的商品

1
2
3
4
5
6
7
8
9
10
11
GET products/_search
{
"query": {
"bool": {
"filter": [ // 过滤子句,不计算得分
{ "range": { "price": { "gt": 100 } } },
{ "term": { "status.keyword": "在售" } }
]
}
}
}
  • 性能优势:过滤条件的结果会被缓存,后续相同查询可直接复用,大幅提升效率。
  • 无得分:响应中 _score 均为 0(或 1.0,不影响排序)。

何时使用查询 vs 过滤?

  1. 使用查询(Query)的场景
    • 需要根据相关性排序(如全文搜索、推荐系统)。
    • 条件涉及文本分词匹配(如 “标题包含 Elasticsearch”)。
  2. 使用过滤(Filter)的场景
    • 条件是精确匹配或范围筛选(如 “日期在近 7 天内”“类型 = 视频”)。
    • 条件频繁重复使用(如 “仅显示已激活的用户”),可利用缓存提升性能。

组合使用:查询 + 过滤

实际场景中,常结合两者优势:用过滤筛选基础条件(高效),用查询计算相关性(精准排序)。

示例:搜索 “手机” 且价格 < 5000 的商品,按相关性排序

1
2
3
4
5
6
7
8
9
10
11
12
13
GET products/_search
{
"query": {
"bool": {
"must": [ // 查询子句:计算得分
{ "match": { "name": "手机" } }
],
"filter": [ // 过滤子句:高效筛选
{ "range": { "price": { "lt": 5000 } } }
]
}
}
}
  • 执行逻辑:先通过 filter 筛选价格 < 5000 的商品,再在结果中通过 must 计算 “手机” 的相关性得分。
  • 性能优化:过滤条件优先执行并缓存,减少后续查询的处理数据量。

性能对比与最佳实践

  1. 性能:过滤 > 查询(因缓存和无得分计算)。
  2. 缓存:
    • 过滤结果默认缓存(可通过 index.queries.cache.enabled 配置)。
    • 查询结果不缓存(得分可能随索引更新变化)。
  3. 最佳实践:
    • 固定条件(如状态、类型)用过滤,动态文本条件用查询。
    • 复杂查询优先通过过滤缩小范围,再进行相关性计算

欢迎关注我的其它发布渠道