Stop ETL’ing Elasticsearch into your warehouse just to JOIN it.
Single-cluster or cross-cluster JOINs on Elasticsearch — via JDBC, ADBC, or Arrow Flight SQL. Pick your scale.
curl -fsSL https://raw.githubusercontent.com/SOFTNETWORK-APP/SoftClient4ES/main/install.sh | bash
softclient4es --host localhost --port 9200 Correlate logs, metrics, and traces across regional ES clusters in a single SQL query.
One incident, several regions, several clusters. Instead of pivoting across N dashboards, JOIN the per-region indices in one query and read the timeline straight across.
Cross-cluster correlation runs on the federation server (Pro+). See the editions & pricing, then the federation operator guide.
-- Illustrative: substitute your own per-region index names.
-- Catalog prefixes route each leg to its regional cluster.
SELECT u.user_id, u.action, e.error_code, e.region
FROM `prod_us`.user_events u
JOIN `prod_eu`.error_events e
ON u.user_id = e.user_id
WHERE e.ts > NOW() - INTERVAL '15' MINUTE
ORDER BY e.ts; From Elasticsearch to DuckDB, parsed once
Every stack pays the same Elasticsearch serialization step on the way out of the cluster: every format its search and SQL endpoints offer is a row-serialized document encoding. SoftClient4ES converts to Apache Arrow once, at the sidecar — and those exact columnar buffers are what land in DuckDB, pandas, or Polars. Zero re-serialization after the sidecar.
It moves what it must, not what it can
A GROUP BY returning 100 rows compiles into an Elasticsearch aggregation:
0.043 s, and 27.1 KB leaves the cluster. Trino’s
Elasticsearch connector performs predicate push-down only, per its documentation, so it
scans all ten million rows out of the cluster first — 5.50 s, and
1.39 GB of egress.
It costs the client far less
Landing all ten million rows as a columnar table costs 2.83 s of client CPU against 24.05 s for Trino’s documented client, and fits in a 2 GB container where that client is OOM-killed even with 8 GB. In an 8 GB budget it completes five concurrent extractions where the documented client completes none and Trino’s fastest completes two.
And it is faster
11.91 s against 14.66 s for Trino’s fastest client and 44.70 s for its documented one — a factor of 1.23 to 3.75 depending on the route. The low end is the serious comparison: nobody extracts ten million rows through the documented client on purpose.
Where Trino is stronger: its fastest client uses less client memory than we do — 617 MB against our 921 MB. Elasticsearch’s own ES|QL pushes the same aggregation down and ties us on that cell.
Measured 2026-08-21 · Elasticsearch 8.18.3 · Trino 483 · sidecar 0.3.0 — scenes show one live run each; the quoted claim is the session median.
SQL for Every Role
One suite, three perspectives — each team finds what they need.
Build Pipelines, Not JSON
Ingest, transform, and materialize data across Elasticsearch indices using standard SQL — no custom scripts, no REST API gymnastics.
- DML — INSERT, UPDATE, DELETE with SQL expressions
- COPY INTO — bulk load from S3, local files (JSON, CSV, Parquet)
- Cross-index JOIN — JOIN across ES indices in one query; ES can’t do this natively
- Materialized Views — persist a pre-joined, pre-aggregated index
- Arrow Flight SQL — Arrow-native, zero-copy columnar streaming — measured on ten million rows
-- Ingest from S3
COPY INTO raw_events
FROM 's3://lake/events.parquet'
FORMAT PARQUET;
-- Materialize a cross-index JOIN
CREATE MATERIALIZED VIEW
order_details AS
SELECT o.id, c.name, SUM(o.amount)
FROM orders o
JOIN customers c
ON o.customer_id = c.id
GROUP BY o.id, c.name; Connect Your BI Tools
Query Elasticsearch with the SQL you already know. Connect Superset, Grafana, Tableau, or DBeaver — no Elasticsearch expertise required.
- JDBC Type 4 — plug into any JDBC-compatible BI tool
- Window functions — AVG OVER, FIRST_VALUE, ARRAY_AGG
- Multi-nested queries — navigate complex ES mappings naturally
- Materialized Views — query persisted, pre-joined data instantly (one of two ES-impossible superpowers, alongside query-time cross-index JOIN)
- ADBC — DuckDB, pandas and Polars via the standard Flight SQL driver
SELECT name, department, salary,
AVG(salary) OVER (
PARTITION BY department
) AS dept_avg,
FIRST_VALUE(name) OVER (
PARTITION BY department
ORDER BY salary DESC
) AS top_earner
FROM employees
WHERE hire_date > '2024-01-01'; Manage Schemas with SQL
CREATE, ALTER, DROP indices with familiar DDL. One unified API across ES 6 through 9 — no version-specific JSON mappings.
- DDL — CREATE TABLE, ALTER TABLE, DROP TABLE
- GatewayApi — one interface for ES 6, 7, 8, and 9
- Interactive REPL — explore, debug, and manage from the terminal
- No ES license required — Apache 2.0 core, external client
CREATE TABLE users (
id KEYWORD,
name TEXT,
email KEYWORD,
age INTEGER,
created_at DATE,
PRIMARY KEY (id)
);
ALTER TABLE users
ADD COLUMN status KEYWORD;
-- Explore from the REPL
SHOW TABLES;
DESCRIBE users; How We Compare
Key differentiators at a glance.
Cross-index JOIN
SoftClient4ES: YesCross-cluster JOIN
SoftClient4ES: YesDDL (CREATE/ALTER/DROP)
SoftClient4ES: YesDML (INSERT/UPDATE/DELETE)
SoftClient4ES: YesWindow functions
SoftClient4ES: YesMaterialized Views
SoftClient4ES: Yes (ES 7.5+)JDBC Driver
SoftClient4ES: Type 4Arrow Flight SQL
SoftClient4ES: YesADBC Driver
SoftClient4ES: YesLicensing: SoftClient4ES core is Apache 2.0. Extensions (Materialized Views, JDBC, ADBC, Arrow Flight SQL) are Elastic v2 license.
Ready to JOIN your Elasticsearch indices?
Drop in a driver, run a cross-index JOIN in minutes — free in Community. No ETL, no warehouse.