文章三十:Elasticsearch SQL实战案例

一、前言

在日常 Elasticsearch(简称 ES)开发中,绝大多数开发者习惯使用原生 DSL 语句实现数据查询、检索与聚合统计。但 ES DSL 存在语法繁琐、学习成本高、可读性差、业务对接效率低等问题,对于后端开发、数据分析人员并不友好。

为此,Elasticsearch 从 7.0 版本开始全面原生支持 ES SQL,兼容标准 SQL 语法,支持查询、筛选、排序、分页、聚合、全文检索等核心能力。开发者无需精通复杂的 DSL,即可快速操作 ES 索引数据,极大降低了 ES 的使用门槛,同时完美适配数据报表、日志分析、业务数据查询等场景。

本文基于 ES 7.x/8.x 稳定版本,结合真实业务索引 page_study_index,从零讲解 ES SQL 核心语法、关键参数、实战场景及避坑方案,所有案例均可直接复制上线使用。

二、环境与索引说明

2.1 适配版本

本文所有语法、参数、请求方式均兼容:Elasticsearch 7.x、8.x 全系列版本,无需额外安装插件,ES 原生开箱即用。

2.2 业务测试索引

本文实战基于业务索引 page_study_index(页面学习数据索引),核心字段结构如下,贴合真实业务场景:

字段名 字段类型 字段说明
id long 数据唯一主键
number integer 排序权重字段
title text/keyword 页面标题
content text 页面内容(支持全文检索)
status integer 状态:0-禁用,1-正常
create_time date 数据创建时间

2.3 执行方式

ES SQL 统一通过 /_sql 接口执行,日常开发最常用 Kibana Dev Tools 调试,生产环境可通过代码 HTTP 请求调用。

复制代码
POST /_sql?format=json
{
  "query": "标准SQL语句",
  "fetch_size": 自定义参数
}

三、核心参数深度解析(重点)

在 ES SQL 接口中,fetch_size 是最容易被误用、忽略的核心参数,也是本文重点讲解的配置项。

3.1 fetch_size 参数详解

  • 参数作用 :控制 ES 服务端 单次流式返回的数据行数,用于批量查询、全量拉取场景,防止一次性加载海量数据导致内存溢出(OOM)、集群压力过大。

  • 默认值1000(未手动配置时,ES 默认单次返回 1000 条数据)

  • 自定义场景:小数据分页可手动调小,大数据批量同步可适当调大(不建议超过 10000)

你常用的排序查询案例:单次仅返回 2 条排序后数据

复制代码
GET _sql
{
  "query": "SELECT * FROM \"page_study_index\" ORDER BY number DESC ",
  "fetch_size":2
}

3.2 关键参数区别(避坑核心)

很多开发者会混淆fetch_sizeLIMIT,二者本质完全不同:

  • fetch_size :服务端分批拉取参数,控制单次网络传输的数据量,属于 底层流式配置

3.3 其他常用公共参数

  • format:指定返回数据格式,支持 json、txt、csv、tsv,开发调试优先用 json

  • timeout:查询超时时间,默认无超时,大数据查询可自定义配置

  • columnar 是否返回列形式的数据

  • filter,通过filter字段,结合dsl+sql

sql 复制代码
GET _sql
{
  "query": """
SELECT * FROM page_study_index ORDER BY number DESC LIMIT 10
  """, 
  "filter":{
    "term": {
      "number": "11"
    }
  }
}
  • translate 使用这个参数可以直接将我们写的sql语句转化成dsl语法。

四、ES SQL 基础语法实战

ES SQL 高度兼容标准 SQL,日常查询、筛选、排序、分页语法与 MySQL 基本一致,学习成本极低。

4.1 基础字段查询

支持查询全字段、指定字段,适配列表展示、数据导出场景

复制代码
-- 查询全部字段,默认1000条
SELECT * FROM page_study_index;

-- 查询指定业务字段(推荐,减少返回冗余数据)
SELECT id, title, number, create_time, status FROM page_study_index;

4.2 条件筛选查询(WHERE)

支持等值查询、模糊查询、时间范围查询、多条件组合,完全适配业务筛选需求

复制代码
-- 1、状态为正常的有效数据
SELECT * FROM page_study_index WHERE status = 1;

-- 2、标题模糊匹配
SELECT * FROM page_study_index WHERE title LIKE '%ES实战%';

-- 3、时间范围筛选
SELECT * FROM page_study_index 
WHERE create_time >= '2026-01-01' AND create_time <= '2026-05-14';

-- 4、多条件组合查询
SELECT title, number FROM page_study_index 
WHERE status = 1 AND number > 10;

4.3 排序查询(ORDER BY)

支持单字段、多字段升降序排序,适配业务列表排序场景

复制代码
-- 单字段排序:按权重number倒序(核心实战场景)
SELECT * FROM page_study_index ORDER BY number DESC;

-- 多字段排序:权重倒序,创建时间倒序
SELECT * FROM page_study_index ORDER BY number DESC, create_time DESC;

五、ES SQL 高阶实战能力

5.1 全文检索(ES 核心特色)

区别于普通数据库 SQL,ES SQL 原生支持全文检索,通过 MATCH 函数替代复杂的 DSL 全文查询,适配文章内容搜索、日志检索场景

sql 复制代码
-- 单字段全文检索:内容包含Elasticsearch
SELECT id, title, content FROM page_study_index WHERE MATCH(content, 'Elasticsearch');

-- 多字段全文检索:标题或内容包含SQL实战
SELECT id, title FROM page_study_index WHERE MATCH((title, content), 'SQL实战');

5.2 聚合统计查询(GROUP BY)

支持各类聚合函数,可快速实现数据统计、报表分析,替代复杂的 ES 聚合 DSL

sql 复制代码
-- 1、按状态分组统计数据总量
SELECT status, COUNT(*) AS total_count FROM page_study_index GROUP BY status;

-- 2、按日期分组,统计每日新增数据量
SELECT DATE(create_time) AS create_day, COUNT(*) AS add_count 
FROM page_study_index 
GROUP BY create_day 
ORDER BY create_day DESC;

-- 3、综合聚合:最大值、最小值、平均值
SELECT MAX(number) AS max_sort, MIN(number) AS min_sort, COUNT(*) AS total 
FROM page_study_index WHERE status = 1;

六、完整综合实战案例(生产可用)

6.1 业务场景

实现有效页面数据分页列表:查询状态正常的业务数据,按权重倒序排序,每页展示 2 条,服务端分批拉取数据,适配前端列表展示。

6.2 完整请求语句

sql 复制代码
POST /_sql?format=json
{
  "query": """
    SELECT id, title, number, create_time
    FROM page_study_index
    WHERE status = 1
    ORDER BY number DESC
    LIMIT 2
  """,
  "fetch_size": 2
}

6.3 响应结果示例

sql 复制代码
{
  "columns": [
    {"name": "id", "type": "long"},
    {"name": "title", "type": "text"},
    {"name": "number", "type": "integer"},
    {"name": "create_time", "type": "datetime"}
  ],
  "rows": [
    [101, "Elasticsearch SQL实战教程", 99, "2026-05-14T10:00:00Z"],
    [100, "ES分页与fetch_size详解", 98, "2026-05-14T09:30:00Z"]
  ]
}

七、Cursor 游标分页

前文提到 fetch_size 是服务端分批拉取参数,很多开发者误以为配置 fetch_size 即可批量获取全量数据,这是典型误区 。单纯配置 fetch_size 仅能获取第一批数据 ,想要获取第二批、第三批剩余数据,必须依赖 ES SQL 提供的 cursor 游标机制

该机制是 ES SQL 适配大数据量流式查询、全量数据导出、无上限分页的核心方案。

8.1 游标分页核心原理

  • fetch_size:定义每一批次返回的数据条数(单次拉取量)

  • cursor:ES 服务端返回的唯一游标标识,用于标记当前查询位置,下次请求携带该游标,即可继续读取下一批数据

  • 生命周期:游标默认存在短暂有效期,查询结束后自动销毁,无内存压力

8.2 完整实战流程(可直接上线)

第一步:首次查询,获取第一批数据 + 游标

首次请求无需携带游标,仅配置 query 和 fetch_size,ES 会返回第一批数据和 cursor 值

sql 复制代码
POST /_sql?format=json
{
  "query": "SELECT id, title, number FROM page_study_index ORDER BY number DESC",
  "fetch_size": 2
}

首次响应结果(含游标)

sql 复制代码
{
  "columns": [
    {"name": "id", "type": "long"},
    {"name": "title", "type": "text"},
    {"name": "number", "type": "integer"}
  ],
  "rows": [
    [101, "Elasticsearch SQL实战教程", 99],
    [100, "ES分页与fetch_size详解", 98]
  ],
  "cursor": "dxlka92mdk1290x...(唯一游标字符串)"
}

第二步:携带游标,循环拉取剩余数据

后续请求不再携带 query,仅携带上一步返回的 cursor 和 fetch_size,持续读取下一批数据

sql 复制代码
GET _sql
{
"cursor": "+6zrA0RGTACEUMFOg0AU3IemBy5+iQlabcLBw27Cihhpuum+yF4aW0CqCzQLjWE/wL/oH3j0/xRsOTuHl3mTl3mZAUWgIA6QAT89Lv4Y6SVw822m01VTm3ZS7ct1ZshklW9N0wIQONd19Xq8hW84I47Tk2EMwufhSIjr99vgCzB6OPAFlzNr6Eew2NzzSqFv0xDfM/R361LojCkdd1630TpBzney87xnK5o5F1OUOKVM7ZVOLL6xeqEjIa+iWSqL22UYmadACTqCpQmv4pukbGMZFlwuH66xYvMXxMfUaosYUCr++UXpHXFPzQDkpwxj+L4H8gsAAP//AwA="
}

终止条件 :当响应结果中 无 cursor 字段 时,代表所有数据读取完毕,循环结束。

8.3 游标分页核心优势

  • 内存安全:配合 fetch_size 分批拉取,不会一次性加载全量数据,彻底避免 OOM

  • 适配场景广:全量数据导出、日志批量同步、大数据量报表统计、无限滚动分页

相关推荐
星晨羽1 小时前
Java通过FTP协议实现文件上传下载
java·开发语言
小则又沐风a1 小时前
初步了解进程的概念
java·linux·服务器·前端
斌果^O^1 小时前
普通 SpringBoot 单体项目改造成微服务(Nacos+Gateway + 内部服务免鉴权)
java·spring boot·spring
摩羯座-小齐1 小时前
java excel级联下拉框
java·excel
砍材农夫1 小时前
物联网 基于netty入门与线程模型探秘简述
java·物联网·struts
GentleDevin1 小时前
IntelliJ Idea常用快捷键(Window和Mac对照表)
java·ide·intellij-idea
Paxon Zhang1 小时前
JavaEE 初阶变强宝典 **线程安全问题,线程状态,锁synchronized**
java·java-ee
阿拉金alakin1 小时前
Java IO 核心类 File、InputStream/OutputStream 实战总结
java·开发语言
财经资讯数据_灵砚智能1 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年5月14日
大数据·人工智能·python·信息可视化·自然语言处理