为 Spring Boot 团队做一个 Elasticsearch 查询工作台:六种模式、语义补全与浏览器直连

一个开源的 Elasticsearch 查询与运维控制台。同一套 Vue 源码,既能作为 Spring Boot starter 嵌入宿主,也能打包成 Chrome MV3 扩展直连 ES。在线演示:dengmeiluan.github.io/esquerystud...

为什么要再做一个 ES 控制台

大部分 Elasticsearch 控制台把「查询」拆成了互不相通的工具页:DSL 构建器一页、SQL 一页、Explain 一页,写完条件树还要手抄 JSON;补全只给关键字,不管字段是 text 还是 keyword,也不管分词器和集群版本;分数不对只能猜,慢查询只能翻日志。

对 Spring Boot 团队还有一层麻烦:为了一个查询台,要再部署一套 Kibana,登录态、菜单、权限和审计都接不回宿主应用。

ESQueryStudio 想解决的就是这条链路:把「怎么写、怎么跑、为什么命中、为什么慢」收进一个连续的查询现场,同时让控制台可以作为 Spring Boot 应用的一部分交付。

六种模式,共用一个现场

控制台不是六个互相跳转的工具页,而是同一份查询现场换视图:

  • DSL 构建器 + 原始编辑器:条件树和 JSON 双向同步;不认识的子句退回原文编辑,不静默丢结构。
  • ES-SQL :支持 _sql 查询、cursor 深分页、字段体检,结果可在表格 / JSON / Tree / 卡片之间切换,并能转成 DSL 继续精修。
  • Lucene:保留原始高亮与命中行,可带去构建器继续改。
  • 查询沙盒 :自由写 DSL、看原始响应、对比 _source 与高亮,适合验证一个假设。
  • PIT 深分页:基于 Point-in-Time 的稳定翻页,游标断了能解释、能续拉,不在 10k 窗口前停住。
  • SQL ⇄ DSL 语法桥:翻译时保留语义差异提示,不把「翻译成功」当成「语义等价」。

切换模式、翻页、刷新都不会把写到一半的查询清空;历史、收藏、草稿和分享深链共用同一套现场。

真正懂 ES 的语义层

补全和 lint 不应该只认识关键字。ESQueryStudio 的语义层会读取当前索引的实时信息:

  • 字段类型、text / keyword 子字段、nested 结构;
  • 分词器、normalizer、同义词与 analysis 设置;
  • 可排序性、日期格式、字段角色;
  • 当前集群版本对应的能力边界。

这些信息一起参与补全、值枚举、执行前检查和语义 lint。例如:在 text 字段上直接排序会提醒走 .keyword;字段不存在、类型不可排序、日期格式不匹配、聚合与排序冲突,都会在执行前给出可操作的修复建议。

条件树改完,JSON 立即更新;JSON 改完,条件树按语义重建。只改一边、另一边静默过期的情况不会发生。

相关性实验室:从「为什么命中」到「为什么慢」

查询工作台和相关性实验室共享同一个查询现场:

  • 打分解剖 :把每个命中文档的 BM25 因子树展开到 tf / idf / boost / norm;
  • 排名侦探:对单个文档追问「为什么是它」,对比不同查询下的得分路径;
  • 查询 X 光:逐子句查看词项、命中数和分析器改写后的实际查询;
  • 子句命中矩阵:哪条子句命中了哪些文档,一屏对齐,专门抓「写了但没起作用」的条件;
  • Boost 调参沙盒:边改权重边看排名变化;
  • Profile 火焰图 :把 profile=true 的查询 / 采集器耗时展开,定位慢在 rewrite、build_scorer 还是 next_doc。

一套 Vue 源码,两种发布形态

这是项目里最想分享的架构选择:控制台只有一套 Vue 3 源码,服务端模式和浏览器模式只切换最底层的 transport。

text 复制代码
ui/ (Vue 3, 52 pages)
  ├─ server mode  → /internal/es/index → Spring Boot console
  └─ browser mode → browserApi.ts      → Elasticsearch REST directly

服务端模式 :Spring Boot 提供 /internal/es/index 适配层,控制台随应用发布,共享宿主登录态、路由、菜单与页面级权限。交付形态支持独立 jar、嵌入式 console 模块、宿主 SPI 和 rebuild-only 引擎。

浏览器模式 :Chrome MV3 扩展内运行同一套源码的 browser 构建,直连 Elasticsearch,不需要后端。首次连接填写 ES 地址和认证,支持多个本机连接档案与顶栏切换;监控、审计、重建 / 迁移作业都落在本机 IndexedDB / localStorage。

这里最重要的不是「把 UI 搬进插件」,而是能力覆盖要有边界且诚实:

  • 浏览器模式没有跨实例分布式锁和代码 provider,系统页展示本机作业锁,配置漂移以本机首次基线为准;
  • 关闭标签页后,service worker 仍按分钟为每条连接写集群 / 每节点 / Top 索引行,并继续做阈值告警;
  • 受限账号缺少 _nodes / _cat / _stats 权限时,只硬依赖 _cluster/health,节点 / 索引明细降级为空,不制造假 RED;
  • 客户端跨集群迁移在关闭标签页后会标记 INTERRUPTED,需要显式恢复。

为了不让「只实现服务端、忘了纯前端」再次发生,仓库里加了 scripts/check-browser-parity.mjs:同时扫描 api.ts、后端 Controller 映射和页面契约前缀,新增端点没有浏览器实现就直接让 CI 失败;确实无法实现的少数端点必须登记原因,并在 UI 显示真实边界。

工程化与质量

  • 52 页、13 分组、11 个功能包;页面契约 META-INF/esquerystudio-pages.json 是前端导航、后端页面门和宿主菜单注册器的唯一事实源。
  • 页面级授权按「连接 × 页面 × 读 / 写」执法,不用隐藏菜单冒充权限。
  • 前后端全量测试:前端 1,519 文件 / 12,209 例,后端覆盖认证、页面授权、重建状态机、映射对账、跨集群迁移与存储档。
  • 真实浏览器探针、权限矩阵、可复现构建、SBOM、CodeQL、OpenSSF Scorecard、Dependabot 一起上。
  • ConsoleHostIntegration、ConsoleAuthDelegate、ConnStore、ConsoleAuditContributor 四个 SPI 分别接管品牌、认证、连接目录和审计,不把宿主业务字段硬编码进平台。

几张真实控制台截图

查询工作台:条件树、原始 DSL、结果和直方图在同一屏。

打分解剖:每个命中文档的 BM25 因子树。

Chrome 扩展:同一套 52 页 Vue 控制台在扩展内直连 ES。

5 分钟体验

独立部署:

bash 复制代码
java -jar esquerystudio-server-1.0.0.jar
# 打开 http://localhost:5601/esquerystudio.html

嵌入 Spring Boot:

xml 复制代码
<dependency>
  <groupId>io.github.dengmeiluan</groupId>
  <artifactId>esquerystudio-console</artifactId>
  <version>1.0.0</version>
</dependency>

ES 客户端栈由宿主以 provided 契约自备;启动时会比对真实类型签名,不匹配直接拒绝启动并给出修复路径。

适合谁

  • 用 Spring Boot / Java 把 Elasticsearch 作为主搜索或日志存储,希望控制台跟应用一起发布;
  • 搜索质量 / 相关性团队,需要把打分、命中矩阵、Profile 放在同一个现场;
  • 平台团队要交付「可查、可改、可治理」的 ES 能力,需要页面级权限、连接目录和审计 SPI;
  • 正在做索引重建、跨集群迁移或容量治理的团队。

最后

项目使用 Apache-2.0 开源,当前是初始版本滚动更新。如果你正在做 Elasticsearch 查询、相关性调优或 Spring Boot 控制台集成,欢迎试用、提 issue 或直接交流使用场景。

相关推荐
养军博客3 小时前
Spring Boot 3.x + Spring Security 6.x 整合 JWT 实战:jjwt 与 java-jwt 两种工具库详解
java·spring boot·springsecurity
txxzjmzlh14 小时前
SpringBoot 统⼀功能处理
java·spring boot·后端
秋天的怀念_David21 小时前
算法一千零一夜 · 第二十六夜 协议的母语
java·spring boot·算法
余槐i1 天前
MySQL 8.0 联合索引走错:为什么加了索引查询反而从 200ms 变成 8s
java·spring boot·mysql·docker·性能优化
nice_lcj5201 天前
【从零理解 Spring AI · 03】Spring AI 在 Spring 生态里的位置
java·spring boot·大模型·spring ai·ai应用开发
AI源码2 天前
旅游推荐管理系统
spring boot
aiks_yuan2 天前
Spring Boot SSE 流式输出变成一次性返回怎么办:大模型打字机效果失效的 5 个原因(Spring Boot 4.1.2 实测)
spring boot
Thomas.Sir2 天前
第15课:SpringBoot连接池详解:HikariCP配置、调优、监控,4.x连接池新特性
java·spring boot
VimorphTech2 天前
每批开 4 个线程,为什么限制不住 TTS 的总并发?
java·spring boot·spring