Skip to content

Commit f70ff1b

Browse files
loicmathieugsmet
authored andcommitted
Add a guide for the Elasticsearch Java API client
1 parent ac43aae commit f70ff1b

File tree

1 file changed

+79
-13
lines changed

1 file changed

+79
-13
lines changed

docs/src/main/asciidoc/elasticsearch.adoc

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
66
= Connecting to an Elasticsearch cluster
77
include::_attributes.adoc[]
88
:categories: data
9-
:summary: This guide covers how to use an Elasticsearch cluster using the low level or high level REST clients.
9+
:summary: This guide covers how to use an Elasticsearch cluster using the low level REST client or the Java API client.
1010

1111
Elasticsearch is a well known full text search engine and NoSQL datastore.
1212

1313
In this guide, we will see how you can get your REST services to use an Elasticsearch cluster.
1414

15-
Quarkus provides two ways of accessing Elasticsearch: via the lower level `RestClient` or via the `RestHighLevelClient` we will call them
16-
the low level and the high level clients.
15+
Quarkus provides three ways of accessing Elasticsearch: via the lower level `RestClient`, via the high level `RestHighLevelClient`, or via the Java API client.
1716

1817
== Prerequisites
1918

@@ -39,7 +38,7 @@ include::{includes}/devtools/create-app.adoc[]
3938
This command generates a Maven structure importing the RESTEasy Reactive/JAX-RS, Jackson, and the Elasticsearch low level client extensions.
4039
After this, the `quarkus-elasticsearch-rest-client` extension has been added to your build file.
4140

42-
If you want to use the high level client instead, replace the `elasticsearch-rest-client` extension by the `elasticsearch-rest-high-level-client` extension.
41+
If you want to use the Java API client instead, replace the `elasticsearch-rest-client` extension by the `elasticsearch-java-client` extension.
4342

4443
[NOTE]
4544
====
@@ -66,21 +65,21 @@ For the Elasticsearch low level client, add:
6665
implementation("io.quarkus:quarkus-elasticsearch-rest-client")
6766
----
6867

69-
For the Elasticsearch high level client, add:
68+
For the Elasticsearch Java API client, add:
7069

7170
[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
7271
.pom.xml
7372
----
7473
<dependency>
7574
<groupId>io.quarkus</groupId>
76-
<artifactId>quarkus-elasticsearch-rest-high-level-client</artifactId>
75+
<artifactId>quarkus-elasticsearch-java-client</artifactId>
7776
</dependency>
7877
----
7978

8079
[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
8180
.build.gradle
8281
----
83-
implementation("io.quarkus:quarkus-elasticsearch-rest-high-level-client")
82+
implementation("io.quarkus:quarkus-elasticsearch-java-client")
8483
----
8584

8685
== Creating your first JSON REST service
@@ -103,7 +102,7 @@ public class Fruit {
103102
Nothing fancy. One important thing to note is that having a default constructor is required by the JSON serialization layer.
104103

105104
Now create a `org.acme.elasticsearch.FruitService` that will be the business layer of our application and store/load the fruits from the Elasticsearch instance.
106-
Here we use the low level client, if you want to use the high level client instead follow the instructions in the <<using-the-high-level-rest-client,Using the High Level REST Client>> paragraph instead.
105+
Here we use the low level client, if you want to use the Java API client instead follow the instructions in the <<using-the-java-api-client,Using the Java API Client>> paragraph instead.
107106

108107
[source,java]
109108
----
@@ -346,10 +345,7 @@ docker run --name elasticsearch -e "discovery.type=single-node" -e "ES_JAVA_OPT
346345

347346
Now let's run our application via Quarkus dev mode:
348347

349-
:devtools-wrapped:
350-
+
351348
include::{includes}/devtools/dev.adoc[]
352-
:!devtools-wrapped:
353349

354350
You can add new fruits to the list via the following curl command:
355351

@@ -365,6 +361,76 @@ And search for fruits by name or color via the flowing curl command:
365361
curl localhost:8080/fruits/search?color=yellow
366362
----
367363

364+
== Using the Java API Client
365+
366+
Here is a version of the `FruitService` using the Java API client instead of the low level one:
367+
368+
[source,java]
369+
----
370+
import co.elastic.clients.elasticsearch.ElasticsearchClient;
371+
import co.elastic.clients.elasticsearch._types.FieldValue;
372+
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
373+
import co.elastic.clients.elasticsearch.core.*;
374+
import co.elastic.clients.elasticsearch.core.search.HitsMetadata;
375+
import jakarta.enterprise.context.ApplicationScoped;
376+
import jakarta.inject.Inject;
377+
import org.acme.elasticsearch.Fruit;
378+
379+
import java.io.IOException;
380+
import java.util.List;
381+
import java.util.stream.Collectors;
382+
383+
@ApplicationScoped
384+
public class FruitService {
385+
@Inject
386+
ElasticsearchClient client; // <1>
387+
388+
public void index(Fruit fruit) throws IOException {
389+
IndexRequest<Fruit> request = IndexRequest.of( // <2>
390+
b -> b.index("fruits")
391+
.id(fruit.id)
392+
.document(fruit)); // <3>
393+
client.index(request); // <4>
394+
}
395+
396+
public Fruit get(String id) throws IOException {
397+
GetRequest getRequest = GetRequest.of(
398+
b -> b.index("fruits")
399+
.id(id));
400+
GetResponse<Fruit> getResponse = client.get(getRequest, Fruit.class);
401+
if (getResponse.found()) {
402+
return getResponse.source();
403+
}
404+
return null;
405+
}
406+
407+
public List<Fruit> searchByColor(String color) throws IOException {
408+
return search("color", color);
409+
}
410+
411+
public List<Fruit> searchByName(String name) throws IOException {
412+
return search("name", name);
413+
}
414+
415+
private List<Fruit> search(String term, String match) throws IOException {
416+
SearchRequest searchRequest = SearchRequest.of(
417+
b -> b.index("fruits")
418+
.query(QueryBuilders.match().field(term).query(FieldValue.of(match)).build()._toQuery()));
419+
420+
SearchResponse<Fruit> searchResponse = client.search(searchRequest, Fruit.class);
421+
HitsMetadata<Fruit> hits = searchResponse.hits();
422+
return hits.hits().stream().map(hit -> hit.source()).collect(Collectors.toList());
423+
}
424+
}
425+
----
426+
427+
In this example you can note the following:
428+
429+
1. We inject an `ElasticsearchClient` inside the service.
430+
2. We create an Elasticsearch index request using a builder.
431+
3. We directly pass the object to the request as the Java API client has a serialization layer.
432+
4. We send the request to Elasticsearch.
433+
368434
== Using the High Level REST Client
369435

370436
Quarkus provides support for the Elasticsearch High Level REST Client but keep in mind that it comes with some caveats:
@@ -387,8 +453,8 @@ Feel free to override the versions of the clients in your applications depending
387453
but be aware of https://www.elastic.co/blog/elastic-license-v2[the new licence of the High Level REST Client] for versions 7.11+:
388454
it is not Open Source and has several usage restrictions.
389455
390-
We will eventually provide an extension for the new Open Source Java client, but it will require changes in your applications
391-
as it is an entirely new client.
456+
We provide an extension for the new Open Source Java API client that is a replacement for the High Level REST CLient,
457+
but it will require changes in your applications as it is an entirely new client.
392458
====
393459

394460
Here is a version of the `FruitService` using the high level client instead of the low level one:

0 commit comments

Comments
 (0)