当前位置: 首页 > news >正文

Elasticsearch 的 SQL 与 DSL 转换

一、前言

Elasticsearch(简称 ES)是基于 Lucene 的分布式搜索与分析引擎,其强大之处在于灵活的 DSL(Domain Specific Language)查询语法
但对于习惯使用 SQL 的开发者来说,DSL 语法初期学习成本不低——尤其是在复杂的聚合、嵌套、分页等场景中。

幸运的是,ES 从 6.x 开始支持了 SQL 查询接口,让我们可以像操作数据库一样使用 SQL。
更妙的是,ES 还提供了 SQL → DSL 的转换接口,让开发者可以编写 SQL,自动生成底层 DSL,从而兼顾可读性与性能优化。


二、为什么要理解 SQL ↔ DSL 转换?

角色关注点
数据分析师想用 SQL 快速查询
后端开发者需要生成或优化 DSL 查询
架构师希望统一查询接口、可视化查询构建
调试/排错需要确认 SQL 翻译出的 DSL 是否高效、正确

理解 SQL 与 DSL 的对应关系,可以让我们:

  • 🚀 快速从 SQL 过渡到原生 DSL;
  • 🔍 精准控制查询性能(例如字段分词、聚合层级);
  • 🧩 动态构建查询(在代码中使用 JSON 模板);
  • 🛠️ 排查 SQL 查询与结果不符的问题。

三、基础示例:SQL → DSL

我们先通过官方 _sql/translate 接口来看看 SQL 是如何被翻译成 DSL 的。

示例 SQL

SELECT title, author, publish_date
FROM books
WHERE author = '鲁迅' AND publish_date >= '1920-01-01'
ORDER BY publish_date DESC
LIMIT 5

转换为 DSL

POST /_sql/translate
{"query": "SELECT title, author, publish_date FROM books WHERE author = '鲁迅' AND publish_date >= '1920-01-01' ORDER BY publish_date DESC LIMIT 5"
}

返回结果:

{"size": 5,"query": {"bool": {"filter": [{ "term": { "author.keyword": "鲁迅" } },{ "range": { "publish_date": { "gte": "1920-01-01" } } }]}},"_source": ["title", "author", "publish_date"],"sort": [{ "publish_date": { "order": "desc" } }]
}

🧠 解读:

  • WHEREbool.filter
  • 精确匹配字段(author.keyword)使用 term
  • 时间条件转为 range
  • ORDER BY 对应 sort
  • LIMIT 对应 size
  • SELECT 对应 _source

四、聚合查询示例

SQL 示例

SELECT category, COUNT(*) AS total
FROM products
WHERE price > 100
GROUP BY category
ORDER BY total DESC

转换结果 DSL

{"size": 0,"query": {"range": {"price": { "gt": 100 }}},"aggs": {"groupby_category": {"terms": {"field": "category.keyword","order": { "_count": "desc" }}}}
}

🧩 说明:

  • GROUP BY 转换为 terms 聚合;
  • COUNT(*) 是默认的 doc_count
  • ORDER BY total DESC 对应 order
  • SQL 层的结果相当于 DSL 中的 aggregations

五、分页与排序

SQL 中的:

SELECT * FROM books ORDER BY publish_date DESC LIMIT 10 OFFSET 20

对应 DSL:

{"from": 20,"size": 10,"sort": [{ "publish_date": { "order": "desc" } }]
}

📘 注意:

  • LIMIT n OFFSET msize + from
  • ES 查询结果默认最多返回 10,000 条,可通过 search_afterscroll 机制分页更大结果集。

六、模糊匹配与全文搜索

SQL

SELECT title FROM articles WHERE title LIKE '%AI%'

DSL

{"query": {"wildcard": {"title": {"value": "*AI*"}}},"_source": ["title"]
}

💡 或者使用更自然的 match 查询(适合中文分词字段):

{"query": {"match": {"title": "AI"}}
}

七、嵌套查询与复杂条件

SQL

SELECT name, age
FROM users
WHERE (city = '北京' OR city = '上海') AND age BETWEEN 20 AND 30

DSL

{"query": {"bool": {"must": [{ "range": { "age": { "gte": 20, "lte": 30 } } }],"should": [{ "term": { "city.keyword": "北京" } },{ "term": { "city.keyword": "上海" } }],"minimum_should_match": 1}},"_source": ["name", "age"]
}

🧠 must 表示 AND,should 表示 OR。
当有多个 should 条件时,记得加上 "minimum_should_match": 1


八、实战技巧:从 JDBC 到 DSL 的双向使用

在 Java、Python 等语言中,我们可以通过 JDBC 驱动 执行 ES SQL 查询。

Connection conn = DriverManager.getConnection("jdbc:es://http://localhost:9200");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT title, price FROM products WHERE price > 100");

但在生产系统中,很多团队会采用以下模式:

业务 SQL 查询
SQL 转换器 _sql/translate
生成 DSL JSON
直接调用 _search 查询结果

优点:

  • SQL 层面可读;
  • DSL 层面可调优;
  • 两者解耦,可灵活缓存和日志记录。

九、常见坑与注意事项

问题原因解决方式
field not found未指定 .keyword 字段对精确匹配用 field.keyword
LIKE 语句性能差wildcard 查询开销大尽量使用 match_phraseprefix
COUNT 出现不一致SQL 聚合默认去重在 DSL 中明确 cardinality
OFFSET 太大性能差from 超过 10000使用 search_after

十、总结

维度SQLDSL
可读性✅ 高❌ 较低
灵活性⚠️ 中等✅ 非常高
性能调优❌ 受限✅ 可完全控制
使用场景快速查询 / 可视化分析后端系统、复杂过滤、聚合统计

💬 结论:开发阶段写 SQL,生产阶段跑 DSL。

通过 _sql/translate,我们可以无缝衔接两者,既享受 SQL 的简洁,又掌握 DSL 的力量。


实用小工具

App Store 截图生成器、应用图标生成器 、在线图片压缩、utc timestamp, ctf tool和 Chrome插件-强制开启复制-护眼模式-网页乱码设置编码
乖猫记账,AI智能分类的最佳聊天记账App。
Elasticsearch可视化客户端工具

http://www.dtcms.com/a/524591.html

相关文章:

  • 快速做网站的软件腾讯企业邮箱电脑版登录入口
  • API测试工具进化:从Postman到Apipost的全局参数管理革命
  • 数据结构——排序的超级详解(Java版)
  • C# 加密解密字符方法Cryptography
  • 教做详情页的网站关键词优化公司电话
  • 中企动力科技股份有限公司网站梵克雅宝官网官方网
  • 自己电脑做电影网站中国建设教育协会培训中心
  • 第三章、React项目国际化介绍(`react-i18next`)
  • RHCA - DO374 | Day03:通过自动化控制器运行剧本
  • 深圳微商城网站建设温州 网站开发
  • 何谓RSS
  • 【SpringCloud】Eureka
  • 网站后台尺寸一般做多大的如何把优酷视频放到网站上
  • 帝国建站模板淘宝网络营销案例分析
  • 企业选择内容+人工智能供应商应该考虑什么?​
  • CI/CD(一)—— 从零搭建 GitLab 全流程(Docker 部署 + 实战指南)
  • 【Android】 Gradle 下载后本地使用方式(macOS / Windows通用)
  • 华为od面经-23届-Java面经
  • Kubernetes LoadBalancer系列|MetalLB介绍与配置
  • 网站制作及管理教程模板网站建设公司 东莞
  • 网站内容品质网站开发的相关语言有哪些
  • 淘宝自己网站怎么建设怎么制作网站编辑页面
  • SQLMap 终极渗透手册(2025全功能版)
  • 微硕WSP4884双N沟MOSFET:汽车智能座舱PMIC“微型稳压核”
  • 【Redis 全解析】高性能内存数据库的原理、实践与优化
  • 手机壳在线设计网站网站都不需要什么备案
  • Ubuntu 系统使用 Docker 部署 Jenkins 详细教程
  • 机器学习(9)正则化
  • 《3D手游光照算力精准分配:动态分层渲染的实践指南》
  • HarmonyOS分布式数据库深度应用