251 lines
8.7 KiB
Plaintext
251 lines
8.7 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 be 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")
|
|
.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)
|
|
.get();
|
|
--------------------------------------------------
|
|
|
|
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().get();
|
|
--------------------------------------------------
|
|
|
|
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-body.html#request-body-search-scroll[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).get(); //max of 100 hits 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.
|
|
--------------------------------------------------
|
|
|
|
[[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)
|
|
.get();
|
|
|
|
// 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().value;
|
|
}
|
|
--------------------------------------------------
|
|
|
|
|
|
[[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")
|
|
.calendarInterval(DateHistogramInterval.YEAR)
|
|
)
|
|
.get();
|
|
|
|
// Get your facet results
|
|
Terms agg1 = sr.getAggregations().get("agg1");
|
|
Histogram 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` object:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
SearchResponse sr = client.prepareSearch(INDEX)
|
|
.setTerminateAfter(1000) <1>
|
|
.get();
|
|
|
|
if (sr.isTerminatedEarly()) {
|
|
// We finished early
|
|
}
|
|
--------------------------------------------------
|
|
<1> Finish after 1000 docs
|
|
|
|
[[java-search-template]]
|
|
=== Search Template
|
|
|
|
See {ref}/search-template.html[Search Template] documentation
|
|
|
|
Define your template parameters as a `Map<String,Object>`:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
Map<String, Object> template_params = new HashMap<>();
|
|
template_params.put("param_gender", "male");
|
|
--------------------------------------------------
|
|
|
|
You can use your stored search templates in `config/scripts`.
|
|
For example, if you have a file named `config/scripts/template_gender.mustache` containing:
|
|
|
|
[source,js]
|
|
--------------------------------------------------
|
|
{
|
|
"query" : {
|
|
"match" : {
|
|
"gender" : "{{param_gender}}"
|
|
}
|
|
}
|
|
}
|
|
--------------------------------------------------
|
|
// NOTCONSOLE
|
|
|
|
Create your search template request:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
SearchResponse sr = new SearchTemplateRequestBuilder(client)
|
|
.setScript("template_gender") <1>
|
|
.setScriptType(ScriptService.ScriptType.FILE) <2>
|
|
.setScriptParams(template_params) <3>
|
|
.setRequest(new SearchRequest()) <4>
|
|
.get() <5>
|
|
.getResponse(); <6>
|
|
--------------------------------------------------
|
|
<1> template name
|
|
<2> template stored on disk in `gender_template.mustache`
|
|
<3> parameters
|
|
<4> set the execution context (ie. define the index name here)
|
|
<5> execute and get the template response
|
|
<6> get from the template response the search response itself
|
|
|
|
You can also store your template in the cluster state:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
client.admin().cluster().preparePutStoredScript()
|
|
.setScriptLang("mustache")
|
|
.setId("template_gender")
|
|
.setSource(new BytesArray(
|
|
"{\n" +
|
|
" \"query\" : {\n" +
|
|
" \"match\" : {\n" +
|
|
" \"gender\" : \"{{param_gender}}\"\n" +
|
|
" }\n" +
|
|
" }\n" +
|
|
"}")).get();
|
|
--------------------------------------------------
|
|
|
|
To execute a stored templates, use `ScriptService.ScriptType.STORED`:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
SearchResponse sr = new SearchTemplateRequestBuilder(client)
|
|
.setScript("template_gender") <1>
|
|
.setScriptType(ScriptType.STORED) <2>
|
|
.setScriptParams(template_params) <3>
|
|
.setRequest(new SearchRequest()) <4>
|
|
.get() <5>
|
|
.getResponse(); <6>
|
|
--------------------------------------------------
|
|
<1> template name
|
|
<2> template stored in the cluster state
|
|
<3> parameters
|
|
<4> set the execution context (ie. define the index name here)
|
|
<5> execute and get the template response
|
|
<6> get from the template response the search response itself
|
|
|
|
You can also execute inline templates:
|
|
|
|
[source,java]
|
|
--------------------------------------------------
|
|
sr = new SearchTemplateRequestBuilder(client)
|
|
.setScript("{\n" + <1>
|
|
" \"query\" : {\n" +
|
|
" \"match\" : {\n" +
|
|
" \"gender\" : \"{{param_gender}}\"\n" +
|
|
" }\n" +
|
|
" }\n" +
|
|
"}")
|
|
.setScriptType(ScriptType.INLINE) <2>
|
|
.setScriptParams(template_params) <3>
|
|
.setRequest(new SearchRequest()) <4>
|
|
.get() <5>
|
|
.getResponse(); <6>
|
|
--------------------------------------------------
|
|
<1> template's body
|
|
<2> template is passed inline
|
|
<3> parameters
|
|
<4> set the execution context (ie. define the index name here)
|
|
<5> execute and get the template response
|
|
<6> get from the template response the search response itself
|