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

在 Ruby 客户端里用 ES|QL

一、两种使用姿势概览

  1. 直接用 ES|QL API(client.esql.query)
  • 最灵活:能选择 JSON / CSV / text 等返回格式,并细调分隔符、locale 等。
  • 默认返回:{"columns":[...], "values":[...]} 的 Hash。
  1. Ruby ES|QL Helper(Elasticsearch::Helpers::ESQLHelper)
  • 把上面的原始结构映射成按列名键入的数组/哈希,更贴近业务代码。
  • 还能对列指定 Proc 做类型转换(如时间→DateTime,IP→IPAddr)。

还可以配合 elastic-esql 这个 gem 用 Ruby 风格链式构建 ES|QL 语句。

二、方式一:直接调用 ES|QL API(最灵活)

query = <<~ESQLFROM sample_data| EVAL duration_ms = ROUND(event.duration / 1000000.0, 1)
ESQLresponse = client.esql.query(body: { query: query })
puts response

默认响应结构(示意)

{"columns" => [{"name"=>"@timestamp", "type"=>"date"},{"name"=>"client.ip", "type"=>"ip"},{"name"=>"event.duration", "type"=>"long"},{"name"=>"message", "type"=>"keyword"},{"name"=>"duration_ms", "type"=>"double"}],"values" => [["2023-10-23T12:15:03.360Z", "172.21.2.162", 3450233, "Connected to 10.1.0.3", 3.5],...]
}

适合需要控制返回格式、自己做映射/导出(如 CSV)的场景。

三、方式二:ES|QL Helper(拿到“即用型” Ruby 对象)

require 'elasticsearch/helpers/esql_helper'response = Elasticsearch::Helpers::ESQLHelper.query(client, query)
response.each { |row| puts row }

输出示意(每行都是 Hash)

{"duration_ms"=>3.5, "message"=>"Connected to 10.1.0.3","event.duration"=>3450233, "client.ip"=>"172.21.2.162","@timestamp"=>"2023-10-23T12:15:03.360Z"}

列级类型转换(parser)

给每个列名配一个 Proc,在“映射到对象”的同时完成转换:

require 'elasticsearch/helpers/esql_helper'
require 'ipaddr'
require 'date'parser = {'@timestamp'    => ->(t) { DateTime.parse(t) },'client.ip'     => ->(i) { IPAddr.new(i) },'event.duration'=> ->(d) { d.to_s }
}rows = Elasticsearch::Helpers::ESQLHelper.query(client, query, parser: parser)
puts rows.first
# => {"duration_ms"=>3.5, "message"=>"Connected ...",
#     "event.duration"=>"3450233", "client.ip"=>#<IPAddr: IPv4:...>,
#     "@timestamp"=>#<DateTime: 2023-10-23T12:15:03+00:00 ...>}

这样你在业务层直接面对 Ruby 类型,而不是原始字符串。

四、用 elastic-esql 构建 ES|QL(更易读、可组合)

require 'elasticsearch'
require 'elastic/esql'client = Elasticsearch::Client.new
index  = 'sample_data'query = Elastic::ESQL.from(index).sort('@timestamp').desc.where('event_duration > 5000000').limit(3).eval({ duration_ms: 'ROUND(event_duration/1000000.0, 1)' })client.esql.query(body: { query: query })

查看生成的 ES|QL 字符串:

query.to_s
# "FROM sample_data | SORT @timestamp DESC | WHERE event_duration > 5000000 | LIMIT 3 | EVAL duration_ms = ROUND(event_duration/1000000.0, 1)"

该库不依赖 elasticsearch-ruby,本质是一个查询构建器;写好 query 后可直接喂给 client.esql.query

五、防注入:参数化查询是必须的

和 SQL 一样,不要把用户输入直接拼进查询。ES|QL 支持把不可信数据作为 params 单独传入,用 ? 占位:

def find_employee_by_name(name)query = Elastic::ESQL.from('employees').keep('first_name', 'last_name', 'height').where('first_name == ?')@client.esql.query(body: { query: query, params: [name] })
end

params 会按顺序替换 ?,从而避免代码注入风险。

六、选择响应格式:JSON / CSV / Text

  • 默认:JSON Hash(columns + values
  • 也可:请求里指定 CSV、text 等格式,并控制分隔符、locale 等,方便导出或兼容旧系统。
  • 使用 Helper 时通常保留默认 JSON,然后映射成 Ruby 对象。

七、实战建议(踩坑少、性能好)

  • 统一入口:面向业务推荐使用 ES|QL Helper,保持代码简洁一致。
  • 类型就地转换:用 parser 在 Helper 层完成时间/IP/数值转换,避免在业务处“到处 parse”。
  • 参数化一律默认开启:所有用户输入都走 ? + params,别拼字符串。
  • 日志与观测:对关键 ES|QL 查询加上上下文(如 request id),便于排障与压测对比。
  • 导出/集成:需要 CSV 或文本格式时,直接用原生 API 选对应 format,少写转换代码。
  • Query Builder 团队规范:针对长查询/拼装查询,统一使用 elastic-esql,可读可测试。

八、完整小结

  • 原生 API:最强灵活性,可控返回格式,但需要自己解析。
  • ES|QL Helper:即开即用,返回 Ruby Hash/Array,并支持列级 Proc 转换。
  • elastic-esql:优雅构建查询字符串,适合复杂、可组合的场景。
  • 安全务必参数化,把用户输入放到 params

把这三者配起来,你就能在 Ruby 环境下把 ES|QL 用得又快又稳、又安全又优雅。

http://www.xdnf.cn/news/18760.html

相关文章:

  • WSL-linux部署IndexTTS 记录(含本地 CUDA/cuDNN 编译依赖说明)
  • 鸿蒙 ArkTS 开发:Number、Boolean、String 三种核心基本数据类型详解(附实战案例)
  • 夜间跌倒检测响应速度↑150%!陌讯多模态骨架追踪算法在智慧养老院的落地实践
  • 手写MyBatis第32弹-设计模式实战:Builder模式在MyBatis框架中的精妙应用
  • Anaconda搭建keras开发环境小记
  • EP01:【DA】数据分析的概述
  • 【LeetCode】分享|如何科学的刷题?
  • 2025年渗透测试面试题总结-31(题目+回答)
  • 基于springboot的高校后勤保修服务系统/基于android的高校后勤保修服务系统app
  • 力扣594:最和谐子序列
  • ViLU: Learning Vision-Language Uncertainties for Failure Prediction
  • Ubuntu 服务器无法 ping 通网站域名的问题解决备忘 ——通常与网络配置有关(DNS解析)
  • 2025年8月第3周AI资讯
  • AI Prompt 的原理与实战
  • assert使用方法
  • 人形机器人——电子皮肤技术路线:光学式电子皮肤及MIT基于光导纤维的分布式触觉传感电子皮肤
  • 基于Spring Cloud与Kafka的支付金融场景面试问答解析
  • Axure RP 9 交互原型设计(Mac 中文)
  • 十、redis 入门 之 redis事务
  • 理想汽车智驾方案介绍 2|MindVLA 方案详解
  • QT-布局管理器
  • 【Docker项目实战】使用Docker部署轻量级LetsMarkdown文本编辑器
  • Java基础第2天总结
  • [两数之和](哈希表做法)
  • 【Python】新手入门:为什么需要类型注解?如何使用Mypy进行静态类型检查?复杂类型注解语法是怎么样的?
  • JH-14回柱绞车优化设计cad+设计说明书+绛重
  • 攻防世界—Confusion1—(模板注入ssti)
  • ADC系统中的信噪比(SNR)
  • Python训练营打卡Day41-Grad-CAM与Hook函数
  • MySQL奔溃,InnoDB文件损坏修复记录