大数据 -176 Elasticsearch Filter DSL 全面实战:过滤查询、排序分页、高亮与批量操作

TL;DR
场景:在日志检索、电商搜索等场景中,需要在 Elasticsearch 中组合过滤、排序、分页、高亮与批量操作。
结论:Filter DSL 负责“是否匹配”、Query 负责“匹配程度”,再配合 sort/from/size/highlight/_mget/_bulk 形成一整套检索实战组合拳。
产出:一篇覆盖 Filter DSL、排序分页、高亮展示与批量读写的实战笔记,可直接套用到线上检索与数据写入链路。
版本矩阵
Filter DSL
基本介绍
Filter DSL:过滤器查询语言)Filter DSL 是 Elasticsearch 提供的一种用于构建过滤查询的方式。与 query 语句不同,过滤器不会计算与文档相关的评分,而是简单地筛选出符合条件的文档。这通常用于只关心是否匹配而不考虑匹配度的情况,如日志分析、数据分类等场景。Filter 查询更高效,适合不需要计算相关性的操作。
实际使用
Elasticsearch 中的所有的查询都会触发相关度得分计算,对于那些不需要相关度得分的场景下,Elasticsearch 以过滤器的形式提供了另一种查询功能,过滤器在概念上类似于查询,但是他们有非常快的执行速度,执行速度快主要有以下两个原因:
过滤器不会计算相关度的得分,所以它们在计算上更快一些
过滤器可以被缓存到内存中,这使得他在重复的搜索查询上,其要比相应的查询快的多
为了理解过滤器,可以将一个查询(像是 match_all,match,bool 等)和一个过滤器结合起来,我们以范围过滤器为例,它允许我们通过一个区间值来过滤文档,这通常被用在数字和日期的过滤上,下面这个例子使用一个被过滤的 查询,其返回值是 200 到 1000 之间(闭区间)的书:
运行的结果如下图所示:
分解上面的例子,被过滤的查询包含一个 match_all 查询和一个过滤器。可以在查询部分放入其他查询,在 Filter 部分放入其他过滤器,在上面的应用场景中,由于所有的在这个范围之内的文档都是平等的(相关度都一样),没有一个文档比另一个文档更相关。所以这个时候就要使用范围过滤器。通常情况下,要决定使用过滤器还是查询,你就需要问自己是否需要相关度得分,如果相关度不重要,那就使用过滤器,否则使用查询。查询和过滤器在概念上类似于 SELECT WHERE 语句。
查询排序
在 Elasticsearch 中,查询结果可以按不同的字段进行排序,默认情况下是按 _score(相关性得分)排序。如果想根据其他字段排序,比如时间戳或价格,可以通过在查询请求中指定 sort 参数来完成。排序可以是升序(asc)或降序(desc),常用于电商、日志分析等需要按时间或数值排序的场景。
相关性评分
默认情况下,返回的结果都是按照相关性进行排序的,最相关的文档排在最前面,首先看看 sort 参数以及如何使用它。为了按照相关性来排序,需要将相关性表示为一个数值,在 Elasticsearch 中,相关性得分由一个浮点数进行表示,并在搜索结果中通过_score 参数返回,默认排序是_score 降序,按照相关性评分升序排序如下:
执行结果如下图所示:
字段值排序
执行的结果如下图所示:
多级排序
执行结果如下图所示:
分页查询
Elasticsearch 分页的方式是非常简单的:
执行结果如下图所示:
结果高亮
结果高亮功能用于在查询结果中突出显示匹配的关键词。当用户搜索特定的词时,Elasticsearch 可以在返回的文档中用 <em> 标签或其他 HTML 元素将匹配的关键词包裹起来,方便前端展示。这个功能常用于搜索引擎或全文检索的结果展示中,提升用户体验。
执行的结果如下图所示:
使用 match 查询的同时,加上一个 highlight 属性:
pre_tags 前置标签
post_tags 后置标签
fields 需要高亮的字段,name 这里声明 title 字段需要高亮
批量操作
Elasticsearch 提供了批量操作的 API,用于一次性执行多个操作,如插入、更新、删除等。这种批量操作可以显著提高处理大量数据的效率,减少与服务器的交互次数。Bulk API 在需要进行大规模数据处理或日志批量写入时非常有用。
批量查询
可以使用 mget 提供批量查询单条查询 ID 的时候,比如很多个 ID,一条一条的查询,网络开销是非常大的。
运行的结果如下图所示:
同一索引批量查询
执行的结果如下图所示:
bulk 批量增删改
Bulk 操作解释将文档的增删改查一系列操作,通过一次请求全部做完,减少网络的传输次数。
示例:
功能:
delete 删除一个文档,只要 1 个 JSON 串就可以 删除的批量操作不需要请求体
create 相当于强制创建 PUT /index/type/id/_create
index 普通的 put 操作,可以是创建文档,也可以是全量替换文档
update 执行的是局部更新 partial update 操作
格式:
每个 JSON 不能换行,相邻 JSON 换行
隔离:
每个操作互不影响,操作失败的行会返回其失败信息
实际用法:
bulk 请求一次不要太大,否则一下会挤压到内存中,性能会下降。
一次请求几千个操作,大小在几 M 正好
bulk 会将要处理的数据载入内存中,所以数据量是有限的,最佳的数据量不是一个确定的值。取决于你的硬件能力、文档复杂性、索引以及搜索的负载
一般建议 1 万-5 万个文档,大小建议是 15MB,默认不能超过 100MB,可以在(ES) config/elasticsearch.yml 中进行设置 http.max_content_length: 10mb
错误速查
其他系列
🚀 AI 篇持续更新中(长期更新)
AI 炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用 AI 工具指南!AI 研究-132 Java 生态前沿 2025:Spring、Quarkus、GraalVM、CRaC 与云原生落地🔗 AI模块直达链接
💻 Java 篇持续更新中(长期更新)
Java-180 Java 接入 FastDFS:自编译客户端与 Maven/Spring Boot 实战 MyBatis 已完结,Spring 已完结,Nginx 已完结,Tomcat 已完结,分布式服务已完结,Dubbo 已完结,MySQL 已完结,MongoDB 已完结,Neo4j 已完结,FastDFS 已完结,OSS 正在更新... 深入浅出助你打牢基础!🔗 Java模块直达链接
📊 大数据板块已完成多项干货更新(300 篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT 案例 详解🔗 大数据模块直达链接
版权声明: 本文为 InfoQ 作者【武子康】的原创文章。
原文链接:【http://xie.infoq.cn/article/ee74954c04be85b4d207e2f66】。文章转载请联系作者。







评论