The easysearch-client library has been updated to version 2.0.2, featuring a complete rewrite that removes legacy constraints and introduces a modern, type-safe API. This guide demonstrates how to integrate and use the new client effectively.
Key Imporvements
- Lightweight & Fast: Unnecessary dependencies have been removed, resulting in a smaller footprint and improved performance.
- Type Safety: Strongly-typed request and response objects reduce runtime errors and improve code maintainability.
- Flexible Execution: Every API supports both synchronous and asynchronous invocation.
- Fluent Query Building: Complex queries can be composed using a builder pattern with functional-style syntax.
- Jackson Integration: Seamless serialization/deserialization between Java objects and Easysearch documents.
Installation
The client requires JDK 8 or higher and uses Jackson for JSON mapping.
Maven:
<dependency>
<groupId>com.infinilabs</groupId>
<artifactId>easysearch-client</artifactId>
<version>2.0.2</version>
</dependency>
Gradle:
implementation 'com.infinilabs:easysearch-client:2.0.2'
Client Initialization
The following example creates a secure HTTPS client with basic authentication:
public static EasysearchClient create() throws Exception {
HttpHost[] hosts = { new HttpHost("localhost", 9200, "https") };
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(null, (chains, authType) -> true)
.build();
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(
sslContext, NoopHostnameVerifier.INSTANCE);
CredentialsProvider credentials = new BasicCredentialsProvider();
credentials.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("username", "password"));
RestClient restClient = RestClient.builder(hosts)
.setHttpClientConfigCallback(builder -> builder
.setDefaultCredentialsProvider(credentials)
.setSSLStrategy(sessionStrategy)
.disableAuthCaching())
.setRequestConfigCallback(config -> config
.setConnectTimeout(30_000)
.setSocketTimeout(300_000))
.build();
EasysearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
return new EasysearchClient(transport);
}
This setup:
- Connects via HTTPS to
localhost:9200 - Trusts all certificates (for development only)
- Authenticates using provided credentials
- Configures connection and socket timeouts
- Wraps the low-level client with the high-level
EasysearchClient
Bulk Indexing Example
The following demonstrates three ways to construct bulk indexing operations:
public static void bulkIndexing() throws Exception {
String docJson = "{\"@timestamp\":\"2023-01-08T22:50:13.059Z\",\"field1\":\"value1\"}";
EasysearchClient client = create();
BulkRequest.Builder bulkBuilder = new BulkRequest.Builder();
// Method 1: Use global index from bulk request
bulkBuilder.index("test1");
for (int i = 0; i < 10; i++) {
IndexOperation op = new IndexOperation.Builder()
.document(JsonData.fromJson(docJson))
.build();
bulkBuilder.operations(new BulkOperation.Builder().index(op).build());
}
// Method 2: Specify index per operation
for (int i = 0; i < 10; i++) {
IndexOperation op = new IndexOperation.Builder()
.document(JsonData.fromJson(docJson))
.index("test2")
.build();
bulkBuilder.operations(new BulkOperation.Builder().index(op).build());
}
// Method 3: Use Map for dynamic document structure
for (int i = 0; i < 10; i++) {
Map<String, Object> doc = new HashMap<>();
doc.put("@timestamp", "2023-01-08T22:50:13.059Z");
doc.put("field1", "value1");
IndexOperation op = new IndexOperation.Builder()
.document(doc)
.index("test3")
.build();
bulkBuilder.operations(new BulkOperation(op));
}
BulkResponse response = client.bulk(bulkBuilder.build());
if (response.errors()) {
response.items().forEach(System.out::println);
}
client._transport().close();
}
Differences in approaches:
- Method 1 relies on the index set at the bulk request level (
test1). Useful when all documents share the same destination. - Method 2 overrides the bulk-level index by specifying it per operation (
test2). Ideal for routing different documents to different indices. - Method 3 uses a
Mapto define document content dynamically (test3). Best when document structure varies or is constructed programmatically.
All three methods produce valid bulk requests, but offer varying degrees of flexibility depending on use case.