| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 | [[java-rest-high-search]]=== Search API[[java-rest-high-document-search-request]]==== Search RequestThe `SearchRequest` is used for any operation that has to do with searchingdocuments, aggregations, suggestions and also offers ways of requestinghighlighting on the resulting documents.In its most basic form, we can add a query to the request:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-basic]--------------------------------------------------<1> Creates the `SeachRequest`. Without arguments this runs against all indices.<2> Most search parameters are added to the `SearchSourceBuilder`. It offers setters for everything that goes into the search request body.<3> Add a `match_all` query to the `SearchSourceBuilder`.===== Optional argumentsLet's first look at some of the optional arguments of a `SearchRequest`:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-indices-types]--------------------------------------------------<1> Restricts the request to an index<2> Limits the request to a typeThere are a couple of other interesting optional parameters:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-routing]--------------------------------------------------<1> Set a routing parameter["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-indicesOptions]--------------------------------------------------<1> Setting `IndicesOptions` controls how unavailable indices are resolved andhow wildcard expressions are expanded["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-preference]--------------------------------------------------<1> Use the preference parameter e.g. to execute the search to prefer localshards. The default is to randomize across shards.===== Using the SearchSourceBuilderMost options controlling the search behavior can be set on the`SearchSourceBuilder`,which contains more or less the equivalent of the options in the search requestbody of the Rest API.Here are a few examples of some common options:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-basics]--------------------------------------------------<1> Create a `SearchSourceBuilder` with default options.<2> Set the query. Can be any type of `QueryBuilder`<3> Set the `from` option that determines the result index to start searchingfrom. Defaults to 0.<4> Set the `size` option that determines the number of search hits to return.Defaults to 10.<5> Set an optional timeout that controls how long the search is allowed totake.After this, the `SearchSourceBuilder` only needs to be added to the`SearchRequest`:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-setter]--------------------------------------------------===== Building queriesSearch queries are created using `QueryBuilder` objects. A `QueryBuilder` exists for every search query type supported by Elasticsearch's {ref}/query-dsl.html[Query DSL].A `QueryBuilder` can be created using its constructor:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-query-builder-ctor]--------------------------------------------------<1> Create a full text {ref}/query-dsl-match-query.html[Match Query] that matchesthe text "kimchy" over the field "user".Once created, the `QueryBuilder` object provides methods to configure the optionsof the search query it creates:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-query-builder-options]--------------------------------------------------<1> Enable fuzzy matching on the match query<2> Set the prefix length option on the match query<3> Set the max expansion options to control the fuzzy    process of the query`QueryBuilder` objects can also be created using the `QueryBuilders` utility class.This class provides helper methods that can be used to create `QueryBuilder` objects using a fluent programming style:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-query-builders]--------------------------------------------------Whatever the method used to create it, the `QueryBuilder` object must be addedto the `SearchSourceBuilder` as follows:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-query-setter]--------------------------------------------------The <<java-rest-high-search-queries, Search Queries>> page gives a list of all available search queries withtheir corresponding `QueryBuilder` objects and `QueryBuilders` helper methods.===== Specifying SortingThe `SearchSourceBuilder` allows to add one or more `SortBuilder` instances. There are four special implementations (Field-, Score-, GeoDistance- and ScriptSortBuilder).["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-sorting]--------------------------------------------------<1> Sort descending by `_score` (the default)<2> Also sort ascending by `_id` field ===== Source filteringBy default, search requests return the contents of the document `_source` but like in the Rest API you can overwrite this behavior. For example, you can turn off `_source` retrieval completely:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-filtering-off]--------------------------------------------------The method also accepts an array of one or more wildcard patterns to control which fields get included or excluded in a more fine grained way:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-filtering-includes]--------------------------------------------------[[java-rest-high-request-highlighting]]===== Requesting HighlightingHighlighting search results can be achieved by setting a `HighlightBuilder` on the`SearchSourceBuilder`. Different highlighting behaviour can be defined for eachfields by adding one or more `HighlightBuilder.Field` instances to a `HighlightBuilder`.["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-highlighting]--------------------------------------------------<1> Creates a new `HighlightBuilder`<2> Create a field highlighter for the `title` field<3> Set the field highlighter type<4> Add the field highlighter to the highlight builderThere are many options which are explained in detail in the Rest API documentation. The RestAPI parameters (e.g. `pre_tags`) are usually changed bysetters with a similar name (e.g. `#preTags(String ...)`).Highlighted text fragments can <<java-rest-high-retrieve-highlighting,later be retrieved>> from the `SearchResponse`.===== Requesting AggregationsAggregations can be added to the search by first creating the appropriate`AggregationBuilder` and then setting it on the `SearchSourceBuilder`. In thefollowing example we create a `terms` aggregation on company names with asub-aggregation on the average age of employees in the company:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-aggregations]--------------------------------------------------The <<java-rest-high-aggregations, Aggregations>> page gives a list of all available aggregations withtheir corresponding `AggregationBuilder` objects and `AggregationBuilders` helper methods.We will later see how to <<java-rest-high-retrieve-aggs,access aggregations>> in the `SearchResponse`.===== Requesting SuggestionsTo add Suggestions to the search request, use one of the `SuggestionBuilder` implementationsthat are easily accessible from the `SuggestBuilders` factory class. Suggestion buildersneed to be added to the top level `SuggestBuilder`, which itself can be set on the  `SearchSourceBuilder`.["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-suggestion]--------------------------------------------------<1> Creates a new `TermSuggestionBuilder` for the `user` field andthe text `kmichy`<2> Adds the suggestion builder and names it `suggest_user`We will later see how to <<java-rest-high-retrieve-suggestions,retrieve suggestions>> from the`SearchResponse`.===== Profiling Queries and AggregationsThe {ref}/search-profile.html[Profile API] can be used to profile the execution of queries and aggregations fora specific search request. in order to use it, the profile flag must be set to true on the `SearchSourceBuilder`:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling]--------------------------------------------------Once the `SearchRequest` is executed the corresponding `SearchResponse` will<<java-rest-high-retrieve-profile-results,contain the profiling results>>.[[java-rest-high-document-search-sync]]==== Synchronous ExecutionWhen executing a `SearchRequest` in the following manner, the client waitsfor the `SearchResponse` to be returned before continuing with code execution:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-execute]--------------------------------------------------[[java-rest-high-document-search-async]]==== Asynchronous ExecutionExecuting a `SearchRequest` can also be done in an asynchronous fashion so thatthe client can return directly. Users need to specify how the response orpotential failures will be handled by passing in appropriate listeners:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-execute-async]--------------------------------------------------<1> Called when the execution is successfully completed.<2> Called when the whole `SearchRequest` fails.==== SearchResponseThe `SearchResponse` that is returned by executing the search provides detailsabout the search execution itself as well as access to the documents returned.First, there is useful information about the request execution itself, like theHTTP status code, execution time or wether the request terminated early or timedout:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-response-1]--------------------------------------------------Second, the response also provides information about the execution on theshard level by offering statistics about the total number of shards that wereaffected by the search, and the successful vs. unsuccessful shards. Possiblefailures can also be handled by iterating over an array off`ShardSearchFailures` like in the following example:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-response-2]--------------------------------------------------[[java-rest-high-retrieve-searchHits]]===== Retrieving SearchHitsTo get access to the returned documents, we need to first get the `SearchHits`contained in the response:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-get]--------------------------------------------------The `SearchHits` provides global information about all hits, like total numberof hits or the maximum score:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-info]--------------------------------------------------Nested inside the `SearchHits` are the individual search results that canbe iterated over:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-singleHit]--------------------------------------------------The `SearchHit` provides access to basic information like index, type, docId andscore of each search hit:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-singleHit-properties]--------------------------------------------------Furthermore, it lets you get back the document source, either as a simpleJSON-String or as a map of key/value pairs. In this map, regular fieldsare keyed by the field name and contain the field value. Multi-valued fields arereturned as lists of objects, nested objects as another key/value map. Thesecases need to be cast accordingly:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-singleHit-source]--------------------------------------------------[[java-rest-high-retrieve-highlighting]]===== Retrieving HighlightingIf <<java-rest-high-request-highlighting,requested>>, highlighted text fragments can be retrieved from each `SearchHit` in the result. The hit object offersaccess to a map of field names to `HighlightField` instances, each of which contains oneor many highlighted text fragments:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-highlighting-get]--------------------------------------------------<1> Get the highlighting for the `title` field<2> Get one or many fragments containing the highlighted field content[[java-rest-high-retrieve-aggs]]===== Retrieving AggregationsAggregations can be retrieved from the `SearchResponse` by first getting theroot of the aggregation tree, the `Aggregations` object, and then getting theaggregation by name.["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-aggregations-get]--------------------------------------------------<1> Get the `by_company` terms aggregation<2> Get the buckets that is keyed with `Elastic`<3> Get the `average_age` sub-aggregation from that bucketNote that if you access aggregations by name, you need to specify theaggregation interface according to the type of aggregation you requested,otherwise a `ClassCastException` will be thrown:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-aggregations-get-wrongCast]--------------------------------------------------<1> This will throw an exception because "by_company" is a `terms` aggregationbut we try to retrieve it as a `range` aggregationIt is also possible to access all aggregations as a map that is keyed by theaggregation name. In this case, the cast to the proper aggregation interfaceneeds to happen explicitly:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-aggregations-asMap]--------------------------------------------------There are also getters that return all top level aggregations as a list:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-aggregations-asList]--------------------------------------------------And last but not least you can iterate over all aggregations and then e.g.decide how to further process them based on their type:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-aggregations-iterator]--------------------------------------------------[[java-rest-high-retrieve-suggestions]]===== Retrieving SuggestionsTo get back the suggestions from a `SearchResponse`, use the `Suggest` object as an entry point and then retrieve the nested suggestion objects:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-suggestion-get]--------------------------------------------------<1> Use the `Suggest` class to access suggestions<2> Suggestions can be retrieved by name. You need to assign them to the correcttype of Suggestion class (here `TermSuggestion`), otherwise a `ClassCastException` is thrown<3> Iterate over the suggestion entries<4> Iterate over the options in one entry[[java-rest-high-retrieve-profile-results]]===== Retrieving Profiling ResultsProfiling results are retrieved from a `SearchResponse` using the `getProfileResults()` method. This method returns a `Map` containing a `ProfileShardResult` object for every shard involved in the `SearchRequest` execution. `ProfileShardResult` are stored in the `Map` using a key that uniquely identifies the shard the profile result corresponds to.Here is a sample code that shows how to iterate over all the profiling results of every shard:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-get]--------------------------------------------------<1> Retrieve the `Map` of `ProfileShardResult` from the `SearchResponse`<2> Profiling results can be retrieved by shard's key if the key is known, otherwise it might be simpler to iterate over all the profiling results<3> Retrieve the key that identifies which shard the `ProfileShardResult` belongs to<4> Retrieve the `ProfileShardResult` for the given shardThe `ProfileShardResult` object itself contains one or more query profile results, one for each queryexecuted against the underlying Lucene index:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-queries]--------------------------------------------------<1> Retrieve the list of `QueryProfileShardResult`<2> Iterate over each `QueryProfileShardResult`Each `QueryProfileShardResult` gives access to the detailed query tree execution, returned as a list of`ProfileResult` objects:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-queries-results]--------------------------------------------------<1> Iterate over the profile results<2> Retrieve the name of the Lucene query<3> Retrieve the time in millis spent executing the Lucene query<4> Retrieve the profile results for the sub-queries (if any)The Rest API documentation contains more information about {ref}/_profiling_queries.html[Profiling Queries] witha description of the {ref}/_profiling_queries.html#_literal_query_literal_section[query profiling information]The `QueryProfileShardResult` also gives access to the profiling information for the Lucene collectors:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-queries-collectors]--------------------------------------------------<1> Retrieve the profiling result of the Lucene collector<2> Retrieve the name of the Lucene collector<3> Retrieve the time in millis spent executing the Lucene collector<4> Retrieve the profile results for the sub-collectors (if any)The Rest API documentation contains more information about profiling information{ref}/_profiling_queries.html#_literal_collectors_literal_section[for Lucene collectors].In a very similar manner to the query tree execution, the `QueryProfileShardResult` objects gives accessto the detailed aggregations tree execution:["source","java",subs="attributes,callouts,macros"]--------------------------------------------------include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-profiling-aggs]--------------------------------------------------<1> Retrieve the `AggregationProfileShardResult`<2> Iterate over the aggregation profile results<3> Retrieve the type of the aggregation (corresponds to Java class used to execute the aggregation)<4> Retrieve the time in millis spent executing the Lucene collector<5> Retrieve the profile results for the sub-aggregations (if any)The Rest API documentation contains more information about {ref}/_profiling_aggregations.html[Profiling Aggregations]
 |