Estimated reading time: 4 minutes
In today’s data-driven applications, fast and flexible search capabilities are critical. Whether you’re powering search for an e-commerce platform, a content management system, or a log analytics tool, integrating Elasticsearch with Java can help you deliver scalable, real-time search functionality with ease.
This post walks you through setting up Elasticsearch, integrating it with a Java application, indexing data, performing search operations, and optimizing performance — everything you need to build a robust search backend.
Why Java and Elasticsearch?
Elasticsearch is a distributed, RESTful search engine built on Apache Lucene. It excels at full-text search, filtering, and real-time analytics. Java, on the other hand, is a versatile, high-performance language commonly used for backend systems. With official Elasticsearch clients for Java like the Elasticsearch Java API Client or the now-deprecated RestHighLevelClient, integrating the two technologies enables developers to create powerful search-driven applications.
Basic operations with Elasticsearch from Java involve:
- Adding dependencies: Include the Elasticsearch Java client library in your project.
- Connecting to Elasticsearch: Establish a connection to your Elasticsearch cluster.
- Creating an index: Define the structure and settings for your data.
- Indexing documents: Add data to your Elasticsearch index.
- Searching documents: Retrieve data based on specific criteria.
- Updating documents: Modify existing data in the index.
- Deleting documents: Remove data from the index.
The Java client simplifies these interactions by providing methods for building requests and parsing responses. It’s designed to handle the complexities of the Elasticsearch API, allowing developers to focus on their application logic.
The official Elasticsearch Java client promotes forward compatibility, ensuring that the client can communicate with equal or greater minor versions of Elasticsearch without issues. It uses a fluent API and builder patterns to construct requests.
Setting Up Elasticsearch
Prerequisites
Before we dive into the Java integration, make sure the followings are installed on your machine:
- Java 17 or later
- Elasticsearch 8.x
- Maven or Gradle
Running Elasticsearch Locally
You can download Elasticsearch from the official website. Once downloaded, extract and run it:
Start Elasticsearch
Run bin/elasticsearch (or binelasticsearch.bat on Windows) to start Elasticsearch with security enabled.
To verify it’s running, open http://localhost:9200 in your browser. You should see a JSON response with cluster information.
Integrating Elasticsearch with Java
Add Dependencies
Use the new Java API Client provided by Elastic. Add the following Maven dependency to your pom.xml:
<dependencies>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.11.0</version>
</dependency>
</dependencies>
For Gradle:
implementation 'co.elastic.clients:elasticsearch-java:8.11.0'
Initialize the Client
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.HealthStatus;
import co.elastic.clients.elasticsearch.cluster.HealthResponse;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
public class ElasticsearchConnector {
public static ElasticsearchClient createClient() {
RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build();
RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
}
public static void main(String[] args) throws Exception {
ElasticsearchClient client = createClient();
HealthResponse health = client.cluster().health();
System.out.println("Cluster Health: " + health.status());
}
}
Indexing Data with Java
Let’s create an index and index a sample product document.
Create a Product POJO
public class Product {
private String id;
private String name;
private String description;
private double price;
// Constructors, getters, and setters
}
Index a Document
Product product = new Product("1", "Wireless Mouse", "Ergonomic wireless mouse", 29.99);
ElasticsearchClient client = ElasticsearchConnector.createClient();
client.index(i -> i
.index("products")
.id(product.getId())
.document(product)
);
System.out.println("Document indexed successfully!");
This will create an index named products and store the JSON-serialized product data inside Elasticsearch.
Searching Data
Now let’s search for the indexed product using a match query.
Match Query Example
SearchResponse<Product> response = client.search(s -> s
.index("products")
.query(q -> q
.match(t -> t
.field("description")
.query("ergonomic")
)
),
Product.class
);
for (Hit<Product> hit : response.hits().hits()) {
System.out.println("Found product: " + hit.source().getName());
}
Term Query Example
SearchResponse<Product> response = client.search(s -> s
.index("products")
.query(q -> q
.term(t -> t
.field("price")
.value(29.99)
)
),
Product.class
);
These queries demonstrate how to perform both full-text and exact-match searches using Java.
Error Handling Best Practices
When dealing with Elasticsearch, network issues, timeouts, or malformed queries can cause exceptions. Here’s how to handle them:
try {
// Your search or indexing logic
} catch (ElasticsearchException e) {
System.err.println("Elasticsearch error: " + e.getMessage());
} catch (IOException e) {
System.err.println("I/O error: " + e.getMessage());
}
Use specific exceptions like ElasticsearchException, and always log error details for better observability.
Optimization Tips
- Index only what you need – Avoid storing unnecessary fields.
- Use
keywordvstextfields wisely – Usekeywordfor sorting/aggregation,textfor full-text search. - Pagination with
fromandsize– Keepsizesmall; use search_after for deep pagination. - Use bulk indexing – For large data sets, use
BulkRequestinstead of indexing documents one by one. - Monitor cluster health – Use the cluster health API to detect bottlenecks early.
Real-World Use Case: Product Search for an E-Commerce App
Imagine you’re building an e-commerce site where users can search for products by name or description.
- Index each product into Elasticsearch when added to your inventory.
- Search using
matchqueries when users type in keywords. - Filter results by price or category using
termqueries orrangefilters. - Paginate results for better UX.
This architecture allows users to quickly find what they’re looking for, even in catalogs with millions of products.
Conclusion
Combining Java with Elasticsearch empowers you to build fast, scalable, and feature-rich search applications. From setting up the client to indexing and querying data, the Elasticsearch Java API offers a seamless integration experience.
Whether you’re building a real-time analytics dashboard or a full-text search engine, this stack offers the flexibility and power you need.
Call to Action
Have you used Elasticsearch with Java in your projects? Got tips or questions? Share your experience in the comments or connect with us to discuss your implementation!


Leave a Reply