Search API 可以执行一个查询操作,返回与查询条件相匹配的结果。 允许跨index查询,也可以跨type查询。 可以使用 query Java API 作为查询语句。 查询的请求体使用 SearchSourceBuilder 构建。 例:

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.index.query.QueryBuilders.*;
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();

注意这里所有的参数都不是必填的,下面的例子就是一个最小化的查询请求:

// MatchAll on the whole cluster with all default options
SearchResponse response = client.prepareSearch().get();
注意:尽管JavaAPI定义了额外的搜索类型 QUERY_AND_FETCH 和 DFS_QUERY_AND_FETCH , 但这些模式其实是底层自动优化时使用的模式,不应该由用户通过API指定。

有关索引操作的更多信息,请查看 REST search

使用分页

首先请阅读 scroll documentation

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(); (1)
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); (2)
1 每次查询最多返回100条结果
2 没有结果返回的时候就停止循环和游标

多条件查询

查看 MultiSearch API Query 文档

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();

long nbHits = 0;
for (MultiSearchResponse.Item item : sr.getResponses()) { (1)
    SearchResponse response = item.getResponse();
    nbHits += response.getHits().getTotalHits();
}
1 可以从 MultiSearchResponse#getResponses() 中获取所有独立的响应

使用聚合

下面这段代码展示了如何在一次查询中加入两个聚合:

SearchResponse sr = client.prepareSearch()
    .setQuery(QueryBuilders.matchAllQuery())
    .addAggregation(
            AggregationBuilders.terms("agg1").field("field")
    )
    .addAggregation(
            AggregationBuilders.dateHistogram("agg2")
                    .field("birth")
                    .dateHistogramInterval(DateHistogramInterval.YEAR)
    )
    .get();

Terms agg1 = sr.getAggregations().get("agg1"); (1)
Histogram agg2 = sr.getAggregations().get("agg2");
1 获取某部分结果

详情请查看 Aggregations Java API

提前结束查询

设置一次查询的最大数,到达这个数量的时候,查询操作就会提前终止。 如果设置了的话,可以在 SearchResponse 对象中使用 isTerminatedEarly() 查看操作是否提前结束。例:

SearchResponse sr = client.prepareSearch(INDEX)
    .setTerminateAfter(1000) (1)
    .get();

if (sr.isTerminatedEarly()) {
    // 提前结束时的逻辑
}
1 查询到1000个文档就停止

搜索模板

查看 Search Template 文档

将模版参数定义成 Map<String,Object> 类型:

Map<String, Object> template_params = new HashMap<>();
template_params.put("param_gender", "male");

可以将模版存储在 config/scripts 目录下。 如果你的脚本在 config/scripts/template_gender.mustache ,则可以这样查询:

{
    "query" : {
        "match" : {
            "gender" : "{{param_gender}}"
        }
    }
}

创建你的查询请求模版:

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 模版名
2 模版存储在本地硬盘 gender_template.mustache
3 模版参数
4 设置执行上下文(可以在这里定义index名称)
5 执行并获取模版的响应
6 从模板响应中获取查询结果

你也可以将模版存储在集群state中:

client.admin().cluster().preparePutStoredScript()
    .setScriptLang("mustache")
    .setId("template_gender")
    .setSource(new BytesArray(
        "{\n" +
        "    \"query\" : {\n" +
        "        \"match\" : {\n" +
        "            \"gender\" : \"{{param_gender}}\"\n" +
        "        }\n" +
        "    }\n" +
        "}")).get();

要执行该模版,需要使用 ScriptService.ScriptType.STORED 类型:

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 模版名
2 模版存储在集群state中
3 模版参数
4 设置执行上下文(可以在这里定义index名称)
5 执行并获取模版的响应
6 从模板响应中获取查询结果

你也可以执行inline(内联)模版:

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 模板体
2 模版是通过inline方式传递的
3 模版参数
4 设置执行上下文(可以在这里定义index名称)
5 执行并获取模版的响应
6 从模板响应中获取查询结果