Part 2 of the Java API client mini-series.
In the last article, we learned how to instantiate the Java API client. In this instalment, we will use the client to index and search data.
We know how to index a document using query DSL in the Kibana console (or using cURL). For example the code in the following listing will index a flight with a random ID as the primary key:
POST flights/_doc
{
"route":"London to New York",
"name":"BA123",
"airline":"British Airways",
"duration_hours":5
}
Let’s index the same document but this time using the Java API client. Remember, we already created the flights
index in the previous section, so all we need to do is use the fluent API to build the query. The listing below demonstrates this query:
public void indexDocument(String indexName, Flight flight) throws IOException {
IndexResponse indexResponse = this.elasticsearchClient.index(
i -> i.index(indexName)
.document(flight)
);
System.out.println("Document indexed"+indexResponse);
}
Executing this query will index a flight into our flights
index. The elasticsearchClient
exposes an index method that can be chained up with other methods such as id and document. In the above case, we didn’t use the ID as we’ve let the system generate it for us.
The document method expects the flight object; did you notice we didn’t do any transformation of the flight Java object to JSON? That’s because, we’ve delegated the responsibility of marshaling and unmarshaling to the JacsonJasonpMapper
class that we associated with the transport object earlier on.
Let’s jump on to writing a query to search for a flight.
Searching
Searching data using queries with Java API client follows the similar path — invoking search method in the ElasticsearchClient
class by passing the required query. There’s one subtle difference though — unlike the other features exposing a client per namespace, the search feature does not. That is, there’s no separate “client” per se, unlike ElasticsearchIndicesClient
.
Let’s just say we wish to search for a route from London to New York: We create a match query providing the “London New York” as the search criteria against the route field in a nicely formed DSL when working with Kibana. This is demonstrated in the listing below:
this.elasticsearchClient.search(searchRequest -> searchRequest
.index(indexName)
.query(queryBuilder ->
queryBuilder.match(matchQBuilder->
matchQBuilder.field("route")
.query(searchText))),Flight.class
);
The search method is expecting a search request, it is provided as a lambda expression to the method as you see above. The query will be written using another lambda function — given a query request (Query.Builder
object), invoke the match function with the MatchQuery.Builder
object. The JSON will be converted to a Flight
Java object, which is why Flight.class
is provided as the argument to the query method.
The response from the search method is a SearchResponse
— so we can capture the results as shown in the snippet below:
SearchResponse searchResponse =
this.elasticsearchClient.search(..)
The searchResponse
consists of results as hits
— which can be iterated through to get to the list of Flights that were returned. The following listing shows the rest of the search request including the Flights returned in the response:
// Capture flights
List<Flight> flights =
(List<Flight>) searchResponse.hits().hits()
.stream().collect(Collectors.toList());
// Or print them to the console
searchResponse.hits().hits()
.stream().forEach(System.out::println);
As you can infer, the searchResponse
object has the results in the hits array — all we need to make sure is to cast the hits to appropriate domain objects (Flight in this case). Full source code of this example is available on my GitHub page here:https://github.com/madhusudhankonda/elasticsearch-clients
This is part 2 of 2 part min-series of Java client for Elasticsearch:
That’s pretty much about Java API client.