2013-08-28 19:24:34 -04:00
|
|
|
[[search]]
|
|
|
|
== Search API
|
|
|
|
|
2014-05-12 22:07:46 -04:00
|
|
|
The search API allows one to execute a search query and get back search hits
|
2013-08-28 19:24:34 -04:00
|
|
|
that match the query. It can be executed across one or more indices and
|
|
|
|
across one or more types. The query can either be provided using the
|
|
|
|
<<query-dsl-queries,query Java API>> or
|
|
|
|
the <<query-dsl-filters,filter 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.FilterBuilders.*;
|
|
|
|
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
|
2014-02-12 22:28:00 -05:00
|
|
|
.setPostFilter(FilterBuilders.rangeFilter("age").from(12).to(18)) // Filter
|
2013-08-28 19:24:34 -04:00
|
|
|
.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();
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
For more information on the search operation, check out the REST
|
2013-09-03 10:15:28 -04:00
|
|
|
{ref}/search.html[search] docs.
|
2013-08-28 19:24:34 -04:00
|
|
|
|
2013-09-03 10:15:07 -04:00
|
|
|
|
2013-09-25 12:17:40 -04:00
|
|
|
[[scrolling]]
|
2013-08-28 19:24:34 -04:00
|
|
|
=== Using scrolls in Java
|
|
|
|
|
2013-09-03 10:15:28 -04:00
|
|
|
Read the {ref}/search-request-scroll.html[scroll documentation]
|
2013-08-28 19:24:34 -04:00
|
|
|
first!
|
|
|
|
|
|
|
|
[source,java]
|
|
|
|
--------------------------------------------------
|
|
|
|
import static org.elasticsearch.index.query.FilterBuilders.*;
|
|
|
|
import static org.elasticsearch.index.query.QueryBuilders.*;
|
|
|
|
|
|
|
|
QueryBuilder qb = termQuery("multi", "test");
|
|
|
|
|
|
|
|
SearchResponse scrollResp = client.prepareSearch(test)
|
|
|
|
.setSearchType(SearchType.SCAN)
|
|
|
|
.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
|
|
|
|
while (true) {
|
2014-10-15 23:35:52 -04:00
|
|
|
|
2013-08-28 19:24:34 -04:00
|
|
|
for (SearchHit hit : scrollResp.getHits()) {
|
|
|
|
//Handle the hit...
|
|
|
|
}
|
2014-10-15 23:35:52 -04:00
|
|
|
scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet();
|
2013-08-28 19:24:34 -04:00
|
|
|
//Break condition: No hits are returned
|
2013-10-06 15:18:43 -04:00
|
|
|
if (scrollResp.getHits().getHits().length == 0) {
|
2013-08-28 19:24:34 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
2013-09-03 10:15:07 -04:00
|
|
|
|
2013-08-28 19:24:34 -04:00
|
|
|
=== Operation Threading
|
|
|
|
|
2014-05-12 22:07:46 -04:00
|
|
|
The search API allows one to set the threading model the operation will be
|
2013-08-28 19:24:34 -04:00
|
|
|
performed when the actual execution of the API is performed on the same
|
|
|
|
node (the API is executed on a shard that is allocated on the same
|
|
|
|
server).
|
|
|
|
|
|
|
|
There are three threading modes.The `NO_THREADS` mode means that the
|
|
|
|
search operation will be executed on the calling thread. The
|
|
|
|
`SINGLE_THREAD` mode means that the search operation will be executed on
|
|
|
|
a single different thread for all local shards. The `THREAD_PER_SHARD`
|
|
|
|
mode means that the search operation will be executed on a different
|
|
|
|
thread for each local shard.
|
|
|
|
|
2013-09-18 12:01:23 -04:00
|
|
|
The default mode is `THREAD_PER_SHARD`.
|
2013-08-28 19:24:34 -04:00
|
|
|
|
2013-09-03 10:15:07 -04:00
|
|
|
|
2013-09-25 12:17:40 -04:00
|
|
|
[[msearch]]
|
2013-08-28 19:24:34 -04:00
|
|
|
=== MultiSearch API
|
|
|
|
|
2013-09-03 10:15:28 -04:00
|
|
|
See {ref}/search-multi-search.html[MultiSearch API Query]
|
2013-08-28 19:24:34 -04:00
|
|
|
documentation
|
|
|
|
|
|
|
|
[source,java]
|
|
|
|
--------------------------------------------------
|
|
|
|
SearchRequestBuilder srb1 = node.client()
|
|
|
|
.prepareSearch().setQuery(QueryBuilders.queryString("elasticsearch")).setSize(1);
|
|
|
|
SearchRequestBuilder srb2 = node.client()
|
|
|
|
.prepareSearch().setQuery(QueryBuilders.matchQuery("name", "kimchy")).setSize(1);
|
|
|
|
|
|
|
|
MultiSearchResponse sr = node.client().prepareMultiSearch()
|
|
|
|
.add(srb1)
|
|
|
|
.add(srb2)
|
|
|
|
.execute().actionGet();
|
|
|
|
|
2013-10-17 03:47:58 -04:00
|
|
|
// You will get all individual responses from MultiSearchResponse#getResponses()
|
2013-08-28 19:24:34 -04:00
|
|
|
long nbHits = 0;
|
2013-10-06 15:18:43 -04:00
|
|
|
for (MultiSearchResponse.Item item : sr.getResponses()) {
|
|
|
|
SearchResponse response = item.getResponse();
|
|
|
|
nbHits += response.getHits().getTotalHits();
|
2013-08-28 19:24:34 -04:00
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
2013-09-03 10:15:07 -04:00
|
|
|
|
2014-05-15 06:36:05 -04:00
|
|
|
[[java-search-aggs]]
|
|
|
|
=== Using Aggregations
|
2013-08-28 19:24:34 -04:00
|
|
|
|
2014-05-15 06:36:05 -04:00
|
|
|
The following code shows how to add two aggregations within your search:
|
2013-08-28 19:24:34 -04:00
|
|
|
|
|
|
|
[source,java]
|
|
|
|
--------------------------------------------------
|
|
|
|
SearchResponse sr = node.client().prepareSearch()
|
|
|
|
.setQuery(QueryBuilders.matchAllQuery())
|
2014-05-15 06:36:05 -04:00
|
|
|
.addAggregation(
|
|
|
|
AggregationBuilders.terms("agg1").field("field")
|
|
|
|
)
|
|
|
|
.addAggregation(
|
|
|
|
AggregationBuilders.dateHistogram("agg2")
|
|
|
|
.field("birth")
|
|
|
|
.interval(DateHistogram.Interval.YEAR)
|
|
|
|
)
|
2013-08-28 19:24:34 -04:00
|
|
|
.execute().actionGet();
|
|
|
|
|
|
|
|
// Get your facet results
|
2014-05-15 06:36:05 -04:00
|
|
|
Terms agg1 = sr.getAggregations().get("agg1");
|
|
|
|
DateHistogram agg2 = sr.getAggregations().get("agg2");
|
2013-08-28 19:24:34 -04:00
|
|
|
--------------------------------------------------
|
|
|
|
|
2014-05-15 06:36:05 -04:00
|
|
|
See <<java-aggs,Aggregations Java API>>
|
2013-08-28 19:24:34 -04:00
|
|
|
documentation for details.
|
2014-11-30 15:17:53 -05:00
|
|
|
|
|
|
|
[[java-search-template]]
|
|
|
|
=== Using Search Templates
|
|
|
|
|
|
|
|
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]
|
|
|
|
--------------------------------------------------
|
|
|
|
{
|
|
|
|
"template" : {
|
|
|
|
"query" : {
|
|
|
|
"match" : {
|
|
|
|
"gender" : "{{param_gender}}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
Execute it with:
|
|
|
|
|
|
|
|
[source,java]
|
|
|
|
--------------------------------------------------
|
|
|
|
SearchResponse sr = client.prepareSearch()
|
|
|
|
.setTemplateName("template_gender")
|
|
|
|
.setTemplateType(ScriptService.ScriptType.FILE)
|
|
|
|
.setTemplateParams(template_params)
|
|
|
|
.get();
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
You can also store your template in a special index named `.scripts`:
|
|
|
|
|
|
|
|
[source,java]
|
|
|
|
--------------------------------------------------
|
|
|
|
client.preparePutIndexedScript("mustache", "template_gender",
|
|
|
|
"{\n" +
|
|
|
|
" \"template\" : {\n" +
|
|
|
|
" \"query\" : {\n" +
|
|
|
|
" \"match\" : {\n" +
|
|
|
|
" \"gender\" : \"{{param_gender}}\"\n" +
|
|
|
|
" }\n" +
|
|
|
|
" }\n" +
|
|
|
|
" }\n" +
|
|
|
|
"}").get();
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
To execute an indexed templates, use `ScriptService.ScriptType.INDEXED`:
|
|
|
|
|
|
|
|
[source,java]
|
|
|
|
--------------------------------------------------
|
|
|
|
SearchResponse sr = client.prepareSearch()
|
|
|
|
.setTemplateName("template_gender")
|
|
|
|
.setTemplateType(ScriptService.ScriptType.INDEXED)
|
|
|
|
.setTemplateParams(template_params)
|
|
|
|
.get();
|
|
|
|
--------------------------------------------------
|