Searching for documents
editSearching for documents
editIndexed documents are available for search in near real-time.
See the Elasticsearch documentation for a full explanation of search requests: search your data, the query DSL, and search APIs.
Simple search query
editThere are many types of search queries that can be combined. We will start with the simple text match query, searching for bikes in the products
index.
The search result has a hits
properties that contains the documents that matched the query along with information about the total number of matches that exist in the index.
The total value comes with a relation that indicates if the total is exact (eq
— equal) or approximate (gte
— greater than or equal).
Each returned document comes with its relevance score and additional information about its location in the index.
String searchText = "bike"; SearchResponse<Product> response = esClient.search(s -> s .index("products") .query(q -> q .match(t -> t .field("name") .query(searchText) ) ), Product.class ); TotalHits total = response.hits().total(); boolean isExactResult = total.relation() == TotalHitsRelation.Eq; if (isExactResult) { logger.info("There are " + total.value() + " results"); } else { logger.info("There are more than " + total.value() + " results"); } List<Hit<Product>> hits = response.hits().hits(); for (Hit<Product> hit: hits) { Product product = hit.source(); logger.info("Found product " + product.getSku() + ", score " + hit.score()); }
Name of the index we want to search. |
|
The query part of the search request (a search request can also have other components like aggregations). |
|
Choose a query variant among the many available. We choose here the match query (full text search). |
|
Configure the match query: we search for a term in the |
|
The target class for the matching documents. We use |
Similarly to get operations, you can fetch documents matching your query as raw JSON by using a corresponding target class instead of Product
, like JSON-P’s JsonValue
or Jackson’s ObjectNode
.
Nested search queries
editElasticsearch allows individual queries to be combined to build more complex search requests. In the example below we will search for bikes with a maximum price of 200.
String searchText = "bike"; double maxPrice = 200.0; // Search by product name Query byName = MatchQuery.of(m -> m .field("name") .query(searchText) )._toQuery(); // Search by max price Query byMaxPrice = RangeQuery.of(r -> r .field("price") .gte(JsonData.of(maxPrice)) )._toQuery(); // Combine name and price queries to search the product index SearchResponse<Product> response = esClient.search(s -> s .index("products") .query(q -> q .bool(b -> b .must(byName) .must(byMaxPrice) ) ), Product.class ); List<Hit<Product>> hits = response.hits().hits(); for (Hit<Product> hit: hits) { Product product = hit.source(); logger.info("Found product " + product.getSku() + ", score " + hit.score()); }
We’re creating the queries for individual criteria separately. |
|
A |
|
Elasticsearch range query accepts a large range of value types. We create here a JSON representation of the maximum price. |
|
The search query is a boolean query that combines the text search and max price queries. |
|
Both queries are added as |
Templated search
editA search template is a stored search that you can run with different variables. Search templates let you change your searches without modifying your application code.
Before running a template search, you first have to create the template. This is a stored script that returns the search request body, and is usually defined as a Mustache template. This stored script can be created outside the application, and also with the Java API Client:
// Create a script esClient.putScript(r -> r .id("query-script") .script(s -> s .lang("mustache") .source("{\"query\":{\"match\":{\"{{field}}\":\"{{value}}\"}}}") ));
To use the search template, use the searchTemplate
method to refer to the script and provide values for its parameters:
SearchTemplateResponse<Product> response = esClient.searchTemplate(r -> r .index("some-index") .id("query-script") .params("field", JsonData.of("some-field")) .params("value", JsonData.of("some-data")), Product.class ); List<Hit<Product>> hits = response.hits().hits(); for (Hit<Product> hit: hits) { Product product = hit.source(); logger.info("Found product " + product.getSku() + ", score " + hit.score()); }
For more in-depth information, see the Elasticsearch search template documentation.
The source code for the examples above can be found in the Java API Client tests.