Connect DBeaver to Elasticsearch. Yes, Really.
A JDBC Type 4 driver that lets DBeaver, DataGrip and Superset query Elasticsearch as if it were a database.
·5 min read
This is Part 6 of the SoftClient4ES series. Previously: Elasticsearch Queries That Never Break in Production, Stop Rewriting Your Elasticsearch Code Every Version Upgrade, It’s 3 AM. Production Is Down. Your Only Tool Is curl., Elasticsearch Schema Management Was Hell. Then Someone Typed SQL., and A 47-Line curl Script to Insert One Document. Seriously.
The BI Gap
A data analytics team uses Elasticsearch to store millions of customer events. They need weekly reports, ad-hoc queries, and dashboards.
Their current workflow:
1. Analyst writes requirements in a Jira ticket2. Developer translates requirements into Elasticsearch JSON DSL3. Developer runs query, exports results to CSV4. Analyst opens CSV in Excel5. Analyst realizes they need a different grouping6. Go back to step 1
Average turnaround: 2-3 days per query.The analyst knows SQL. The data is in Elasticsearch. The gap between the two is a developer acting as a human translator.
What if the analyst could just… connect directly?
One JAR. One Connection String. Full SQL.
The SoftClient4ES JDBC driver turns Elasticsearch into a SQL database that any JDBC-compatible tool can query.
JDBC URL: jdbc:elastic://localhost:9200Driver class: app.softnetwork.elastic.jdbc.ElasticDriverThat’s it. Two lines of configuration. No Elasticsearch knowledge required on the client side.
Setting Up DBeaver (Step by Step)
Step 1: Download the Driver JAR
Download the self-contained fat JAR for your Elasticsearch version:
| Elasticsearch Version | Artifact |
|---|---|
| ES 6.x | softclient4es6-jdbc-driver-0.3.0.jar |
| ES 7.x | softclient4es7-jdbc-driver-0.3.0.jar |
| ES 8.x | softclient4es8-jdbc-driver-0.3.0.jar |
| ES 9.x | softclient4es9-jdbc-driver-0.3.0.jar |
One JAR. No external dependencies. No Scala version suffix. Works with any JVM (Java 8+).
Step 2: Add a New Driver in DBeaver
- Open DBeaver > Database > Driver Manager
- Click New
- Fill in:
- Driver Name: SoftClient4ES
- Class Name:
app.softnetwork.elastic.jdbc.ElasticDriver - URL Template:
jdbc:elastic://{host}:{port} - Default Port:
9200
-
Go to the Libraries tab
-
Click Add File and select the downloaded JAR
-
Click OK
Step 3: Create a Connection
- Database > New Database Connection
- Select the SoftClient4ES driver
- Enter your Elasticsearch host and port
- Click Test Connection — should succeed immediately
- Click Finish
Step 4: Query
SELECT customer_segment, COUNT(*) as order_count, SUM(amount) as total_revenue, AVG(amount) as avg_order_valueFROM ordersWHERE status = 'completed' AND created_at >= '2025-01-01'GROUP BY customer_segmentORDER BY total_revenue DESC;In DBeaver. With syntax highlighting. With export to CSV, Excel, or JSON.
The analyst went from “file a Jira ticket” to “run the query yourself” in under five minutes.
Connection URL Parameters
The JDBC URL supports a range of connection parameters:
jdbc:elastic://host:port?param=value¶m2=value2| Parameter | Description | Example |
|---|---|---|
user / username | Authentication username | user=admin |
password | Authentication password | password=secret |
ssl | Enable HTTPS | ssl=true |
apiKey / api-key | API key authentication | apiKey=mykey123 |
bearerToken / bearer-token | Bearer token authentication | bearerToken=tok123 |
connectionTimeout / connection-timeout | Connection timeout | connectionTimeout=10s |
socketTimeout / socket-timeout | Socket/read timeout | socketTimeout=60s |
Authentication examples:
# Basic authjdbc:elastic://es-prod:9200?user=admin&password=secret# API keyjdbc:elastic://es-prod:9200?apiKey=mykey123# Bearer token + SSLjdbc:elastic://es-prod:9200?ssl=true&bearerToken=my-token# Custom timeoutsjdbc:elastic://es-prod:9200?connectionTimeout=10s&socketTimeout=120sWhat Works Through JDBC
Everything. The JDBC driver exposes the full SoftClient4ES SQL surface.
DDL (Schema Management)
CREATE TABLE products ( id KEYWORD NOT NULL, name VARCHAR, price DOUBLE DEFAULT 0.0, PRIMARY KEY (id));ALTER TABLE products ADD COLUMN IF NOT EXISTS stock INT;DESCRIBE TABLE products;SHOW TABLES LIKE 'product%';SHOW CREATE TABLE products;DML (Data Operations)
INSERT INTO products (id, name, price)VALUES ('p1', 'Laptop', 999.99);UPDATE products SET price = 899.99 WHERE id = 'p1';DELETE FROM products WHERE stock = 0;COPY INTO products FROM '/data/catalog.jsonl';DQL (Queries)
SELECT name, priceFROM productsWHERE price > 100ORDER BY price DESCLIMIT 50;
SELECT category, COUNT(*) as product_count, AVG(price) as avg_priceFROM productsGROUP BY categoryHAVING COUNT(*) > 5;Materialized Views
-- Automatic refresh (requires ES license)CREATE MATERIALIZED VIEW orders_with_customers_mvREFRESH EVERY 8 SECONDSWITH (delay = '1s', user_latency = '1s')ASSELECT o.id, o.amount, c.name AS customer_nameFROM orders AS oJOIN customers AS c ON o.customer_id = c.id;
-- Without ES license: schedule this yourself (cron, Airflow, etc.)REFRESH MATERIALIZED VIEW orders_with_customers_mv;SELECT * FROM orders_with_customers_mvWHERE customer_name = 'Alice';Supported Tools
| Tool | Status | Use Case |
|---|---|---|
| DBeaver | Tested | Ad-hoc queries, data exploration, export |
| DataGrip | Tested | Developer SQL IDE |
| Apache Superset | Tested | Dashboards, BI reporting (dedicated dialect) |
| Tableau | Compatible | Dashboards, BI reporting |
| Power BI | Compatible | Dashboards, BI reporting |
| DbVisualizer | Compatible | Database management |
| Any JDBC app | Compatible | Java, Scala, Kotlin applications |
Programmatic JDBC Usage
Maven / Gradle / sbt
<!-- Maven --><dependency> <groupId>app.softnetwork.elastic</groupId> <artifactId>softclient4es8-jdbc-driver</artifactId> <version>0.3.0</version></dependency>// Gradleimplementation 'app.softnetwork.elastic:softclient4es8-jdbc-driver:0.3.0'// sbtresolvers += "Softnetwork" at "https://softnetwork.jfrog.io/artifactory/releases/"libraryDependencies += "app.softnetwork.elastic" % "softclient4es8-jdbc-driver" % "0.3.0"Note: The artifact has no _2.12 or _2.13 suffix — it’s Scala-version-independent.
Java Example
import java.sql.*;// Connection (driver auto-registers via SPI)Connection conn = DriverManager.getConnection( "jdbc:elastic://localhost:9200");// QueryStatement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery( "SELECT name, price FROM products WHERE price > 100 ORDER BY price DESC");while (rs.next()) { System.out.println(rs.getString("name") + " - $" + rs.getDouble("price"));}// DMLint count = stmt.executeUpdate( "INSERT INTO products (id, name, price) VALUES ('p42', 'Widget', 19.99)");System.out.println("Inserted: " + count);// PreparedStatementPreparedStatement pstmt = conn.prepareStatement( "SELECT * FROM products WHERE category = ? AND price > ?");pstmt.setString(1, "Electronics");pstmt.setDouble(2, 50.0);ResultSet rs2 = pstmt.executeQuery();// Cleanuprs.close();stmt.close();conn.close();Kotlin Example
DriverManager.getConnection("jdbc:elastic://localhost:9200").use { conn -> conn.createStatement().use { stmt -> val rs = stmt.executeQuery("SELECT name, price FROM products ORDER BY price DESC LIMIT 10") while (rs.next()) { println("${rs.getString("name")} — $${rs.getDouble("price")}") } }}Architecture
┌──────────────┐ JDBC ┌──────────────────────┐ REST API ┌───────────────┐│ DBeaver │ ────────────── │ SoftClient4ES │ ──────────────── │ Elasticsearch ││ Tableau │ SQL over │ JDBC Driver │ Optimized DSL │ 6/7/8/9 ││ DataGrip │ JDBC │ (fat JAR, no deps) │ │ ││ Your App │ │ │ │ │└──────────────┘ └──────────────────────┘ └───────────────┘The driver is a pure JDBC Type 4 driver — no native libraries, no middleware. Your application sends SQL; the driver translates it to optimized Elasticsearch REST API calls and returns standard JDBC ResultSets.
Key architectural decisions:
- Self-contained fat JAR: All dependencies bundled. Drop it into DBeaver’s driver folder and go.
- Per-connection ActorSystem: Each JDBC connection manages its own lifecycle — no shared state, no concurrency issues.
- Client-side PreparedStatement: Parameter substitution happens before SQL parsing — supports all Java date/time types with proper escaping.
- Streaming under the hood: Large result sets use Akka Streams internally, materialized to JDBC ResultSets.
Editions
The JDBC driver is available as a free community edition:
| Feature | Community (free) | Pro | Enterprise |
|---|---|---|---|
| Full DDL / DML / DQL | Yes | Yes | Yes |
| JDBC driver | Yes | Yes | Yes |
| Materialized Views | Yes (1 view) | Yes (50 views) | Unlimited |
| Priority support | — | — | Yes |
The community driver JAR includes the community extensions library (materialized views, capped at 1).
Before & After
| Scenario | Before | After |
|---|---|---|
| Analyst needs a report | File Jira ticket → wait 2-3 days | Open DBeaver → query directly |
| Data exploration | Ask a developer to translate to JSON DSL | Write SQL, iterate instantly |
| Dashboard creation | Export pipeline: ES → CSV → Excel → Tableau | Tableau → JDBC → ES (live) |
| Application integration | Custom REST client + JSON parsing | Standard JDBC (DriverManager.getConnection) |
| Team onboarding | Learn Elasticsearch Query DSL | Use SQL (everyone knows it) |
Getting Started
Quick Test (REPL)
# Install the REPLcurl -fsSL https://raw.githubusercontent.com/SOFTNETWORK-APP/softclient4es/main/install.sh | bash# Connect and verify SQL workssoftclient4es --host localhost --port 9200sql> SHOW TABLES;sql> SELECT COUNT(*) FROM your_index;sql> exitGoodbye!DBeaver Setup
- Download the JAR for your ES version
- Add it as a driver in DBeaver (Driver Manager > New)
- Create a connection:
jdbc:elastic://your-host:9200 - Start querying
Java/Scala Application
- Add the Maven/Gradle/sbt dependency
DriverManager.getConnection("jdbc:elastic://host:9200")- Use standard JDBC API
Resources
- SQL Reference: Full SQL Documentation
- REPL Documentation: Full REPL Guide
- GitHub: SoftClient4ES Repository
- Discussions: Ask Questions
- LinkedIn: SoftNetwork
- Website:
softclient4es.dev
How long does your team wait for data extracts from Elasticsearch? If the answer involves Jira tickets and developer time, there might be a faster way.
P.S. — The JDBC driver works on Elasticsearch 6, 7, 8, and 9. One JAR per ES version. No Scala dependency. Drop it in and go.
Next in the series: JOINs in Elasticsearch? One SQL Statement. Zero Application Code. — how materialized views bring real JOINs, precomputed aggregations, and continuous refresh to Elasticsearch.
This post first appeared on Medium. This is the maintained version — free to read, no account, and corrected as the product moves.
Try it on your own cluster
SoftClient4ES runs SQL — DDL, DML, queries, cross-index JOINs and materialized views — on Elasticsearch 6 through 9.