149 lines
5.3 KiB
Plaintext
149 lines
5.3 KiB
Plaintext
[[java-search]]
|
|
== Search API
|
|
|
|
The search API allows one to execute a search query and get back search hits
|
|
that match the query. It can be executed across one or more indices and
|
|
across one or more types. The query can provided using the <<java-query-dsl,query Java API>>.
|
|
The body of the search request is built using the `SearchSourceBuilder`. Here is an example:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
import org.elasticsearch.action.search.SearchResponse;
|
|
import org.elasticsearch.action.search.SearchType;
|
|
import org.elasticsearch.index.query.QueryBuilders.*;
|
|
--------------------------------------------------
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
SearchResponse response = client.prepareSearch("index1", "index2")
|
|
.setTypes("type1", "type2")
|
|
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
|
|
.setQuery(QueryBuilders.termQuery("multi", "test")) // Query
|
|
.setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18)) // Filter
|
|
.setFrom(0).setSize(60).setExplain(true)
|
|
.execute()
|
|
.actionGet();
|
|
--------------------------------------------------
|
|
|
|
Note that all parameters are optional. Here is the smallest search call
|
|
you can write:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
// MatchAll on the whole cluster with all default options
|
|
SearchResponse response = client.prepareSearch().execute().actionGet();
|
|
--------------------------------------------------
|
|
|
|
NOTE: Although the Java API defines the additional search types QUERY_AND_FETCH and
|
|
DFS_QUERY_AND_FETCH, these modes are internal optimizations and should not
|
|
be specified explicitly by users of the API.
|
|
|
|
For more information on the search operation, check out the REST
|
|
{ref}/search.html[search] docs.
|
|
|
|
|
|
[[java-search-scrolling]]
|
|
=== Using scrolls in Java
|
|
|
|
Read the {ref}/search-request-scroll.html[scroll documentation]
|
|
first!
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
import static org.elasticsearch.index.query.QueryBuilders.*;
|
|
|
|
QueryBuilder qb = termQuery("multi", "test");
|
|
|
|
SearchResponse scrollResp = client.prepareSearch(test)
|
|
.addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)
|
|
.setScroll(new TimeValue(60000))
|
|
.setQuery(qb)
|
|
.setSize(100).execute().actionGet(); //100 hits per shard will be returned for each scroll
|
|
//Scroll until no hits are returned
|
|
do {
|
|
for (SearchHit hit : scrollResp.getHits().getHits()) {
|
|
//Handle the hit...
|
|
}
|
|
|
|
scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
|
|
} while(scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.
|
|
--------------------------------------------------
|
|
[NOTE]
|
|
====
|
|
The size-parameter is per shard, so if you run a query against multiple indices (leading to many shards being involved in the query) the result might be more documents per execution of the scroll than you would expect!
|
|
====
|
|
|
|
[[java-search-msearch]]
|
|
=== MultiSearch API
|
|
|
|
See {ref}/search-multi-search.html[MultiSearch API Query]
|
|
documentation
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
SearchRequestBuilder srb1 = client
|
|
.prepareSearch().setQuery(QueryBuilders.queryStringQuery("elasticsearch")).setSize(1);
|
|
SearchRequestBuilder srb2 = client
|
|
.prepareSearch().setQuery(QueryBuilders.matchQuery("name", "kimchy")).setSize(1);
|
|
|
|
MultiSearchResponse sr = client.prepareMultiSearch()
|
|
.add(srb1)
|
|
.add(srb2)
|
|
.execute().actionGet();
|
|
|
|
// You will get all individual responses from MultiSearchResponse#getResponses()
|
|
long nbHits = 0;
|
|
for (MultiSearchResponse.Item item : sr.getResponses()) {
|
|
SearchResponse response = item.getResponse();
|
|
nbHits += response.getHits().getTotalHits();
|
|
}
|
|
--------------------------------------------------
|
|
|
|
|
|
[[java-search-aggs]]
|
|
=== Using Aggregations
|
|
|
|
The following code shows how to add two aggregations within your search:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
SearchResponse sr = client.prepareSearch()
|
|
.setQuery(QueryBuilders.matchAllQuery())
|
|
.addAggregation(
|
|
AggregationBuilders.terms("agg1").field("field")
|
|
)
|
|
.addAggregation(
|
|
AggregationBuilders.dateHistogram("agg2")
|
|
.field("birth")
|
|
.dateHistogramInterval(DateHistogramInterval.YEAR)
|
|
)
|
|
.execute().actionGet();
|
|
|
|
// Get your facet results
|
|
Terms agg1 = sr.getAggregations().get("agg1");
|
|
DateHistogram agg2 = sr.getAggregations().get("agg2");
|
|
--------------------------------------------------
|
|
|
|
See <<java-aggs,Aggregations Java API>>
|
|
documentation for details.
|
|
|
|
|
|
[[java-search-terminate-after]]
|
|
=== Terminate After
|
|
|
|
The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early.
|
|
If set, you will be able to check if the operation terminated early by asking for `isTerminatedEarly()` in the
|
|
`SearchResponse` onject:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
SearchResponse sr = client.prepareSearch(INDEX)
|
|
.setTerminateAfter(1000) <1>
|
|
.get();
|
|
|
|
if (sr.isTerminatedEarly()) {
|
|
// We finished early
|
|
}
|
|
--------------------------------------------------
|
|
<1> Finish after 1000 docs
|