Introducing the ES|QL query builder for the Elasticsearch Ruby Client

Learn how to use the recently released ES|QL query builder for the Elasticsearch Ruby Client. A tool to build ES|QL queries more easily with Ruby code.

We recently released elastic-esql, a Ruby gem published under the Apache 2 license. This gem allows you to build Elastic's ES|QL queries in idiomatic Ruby, which you can then use with the ES|QL query API. ES|QL allows developers to filter, transform, and analyze data stored in Elasticsearch via queries. It uses "pipes" ( | ) to work with the data step by step. The gem uses Ruby functions instead, which you can chain to the original object to build more complex queries:

ESQL:

FROM sample_data | LIMIT 2 | SORT @timestamp DESC

Ruby:

Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending

Installation

The gem can be installed from RubyGems with:

gem install elastic-esql

Or it can be added to a project's Gemfile:

gem 'elastic-esql'

Usage

You can either build a complete query at once or create a query object with a source command like from or row and then chain ES|QL methods to build on it.

query = Elastic::ESQL.from('sample_data')
query.limit(2).sort('@timestamp')

The gem translates the code to ES|QL on the to_s method, so it returns the ES|QL query when it is printed out or is cast as a String:

query = Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending
query.to_s
# => "FROM sample_data | LIMIT 2 | SORT @timestamp DESC"

You can instantiate a query object and mutate its initial state by using the ! equivalents of each function:

query = Elastic::ESQL.from('sample_data')
query.to_s
# => "FROM sample_data"
query.limit!(2).sort!('@timestamp')
query.to_s
# => "FROM sample_data | LIMIT 2 | SORT @timestamp"

The tool provides convenient ways to chain extra steps to an ES|QL function, such as enrich and sort. Once you call enrich on an Elastic::ESQL object, you can chain on and with to it:

esql.enrich!('policy').on('a').with({ name: 'language_name' })

You can also chain desc, asc, nulls_first and nulls_last to your query after using sort:

Elastic::ESQL.from('sample_data').sort('@timestamp').asc.to_s
# => 'FROM sample_data | SORT @timestamp ASC'

Elastic::ESQL.from('sample_data').sort('@timestamp').desc.nulls_first.to_s
# => 'FROM sample_data | SORT @timestamp DESC NULLS FIRST'

It also supports custom Strings, in case you want to write the ES|QL query yourself, or use a feature that hasn't been added to the library yet. custom will join the strings at the end of the query. It will add them as they're sent to the function, without adding any pipe characters. They'll be combined to the rest of the query by a space character.

esql = Elastic::ESQL.from('sample_data')
esql.custom('| MY_VALUE = "test value"').to_s
# => 'FROM sample_data | MY_VALUE = "test value"'

You can also chain custom functions:

esql.custom('| MY_VALUE = "test value"').custom('| ANOTHER, VALUE')
'FROM sample_data | MY_VALUE = "test value" | ANOTHER, VALUE'

Using the ES|QL Query Builder with the Ruby client

You can use the query builder directly with elasticsearch-ruby and the esql.query API by sending the query object:

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 })

You can also use it with the ES|QL Helper from the Elasticsearch Ruby client, find out more:

require 'elasticsearch/helpers/esql_helper'

Elasticsearch::Helpers::ESQLHelper.query(client, query)

As a standalone tool

The gem is designed as a standalone tool to build ES|QL queries in an idiomatic way. It has no runtime dependencies; you can use it with the official Elasticsearch Ruby client, or on its own.

The generated query can be used with the esql.query API in any way an application interacts with the Elasticsearch API (Ruby or not). Once a query is built with elastic-esql, the generated String can be sent to the API as the query parameter in the request body.

I previously wrote about using Elasticsearch with popular Ruby tools. This gem can be used with any of the popular Ruby tools to query Elasticsearch with ES|QL.

Conclusion

This library is in active development, and the final API hasn't been completed yet. It's currently released as a technical preview. If you have any feedback on the current API or general usage, please don't hesitate to open a new issue. Please refer to the README to learn more about the Ruby ES|QL Query Builder.

Ready to try this out on your own? Start a free trial.

Want to get Elastic certified? Find out when the next Elasticsearch Engineer training is running!

Related content

Don't leave metrics on the table: query them with the ES|QL TS command

May 14, 2026

Don't leave metrics on the table: query them with the ES|QL TS command

Recalibrate your mental model for time series queries: learn why FROM can produce inaccurate results for metrics, how TS fixes that, and when to use each command.

 Approximate queries in Elasticsearch ES|QL: 100x faster on billions of records, with built-in confidence intervals

May 14, 2026

Approximate queries in Elasticsearch ES|QL: 100x faster on billions of records, with built-in confidence intervals

ES|QL now supports approximate query execution. Add one line to your queries, and get results orders of magnitude faster, with built-in confidence intervals that tell you exactly how much to trust them.

Elasticsearch ES|QL “schema on read”: Your unmapped fields were there all along

May 12, 2026

Elasticsearch ES|QL “schema on read”: Your unmapped fields were there all along

ES|QL's new unmapped fields feature makes any never-mapped field queryable against historical data (no reindexing needed).

From averages to any percentile: Elasticsearch ships native exponential histogram support in ES|QL

May 8, 2026

From averages to any percentile: Elasticsearch ships native exponential histogram support in ES|QL

Query any percentile at any time. Elasticsearch natively stores OTel exponential histograms and lets you analyze distributions in ES|QL without fixed buckets or lossy conversions.

30x faster than Prometheus: How we rebuilt Elasticsearch as a leading columnar metrics datastore

30x faster than Prometheus: How we rebuilt Elasticsearch as a leading columnar metrics datastore

Elasticsearch now stores OTel metrics at 3.75 bytes per data point and queries them up to 30x faster than Prometheus. Here's how we rebuilt TSDS and ES|QL.

Ready to build state of the art search experiences?

Sufficiently advanced search isn’t achieved with the efforts of one. Elasticsearch is powered by data scientists, ML ops, engineers, and many more who are just as passionate about search as your are. Let’s connect and work together to build the magical search experience that will get you the results you want.

Try it yourself