SearchRequest
用于与搜索文档、聚合、suggestions相关的任何操做,还提供了在结果文档上请求高亮的方法。编程
在最基本的表单中,咱们能够向请求添加查询:segmentfault
SearchRequest searchRequest = new SearchRequest(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery()); searchRequest.source(searchSourceBuilder);
SeachRequest
,没有参数,这将针对全部索引运行。SearchSourceBuilder
中,它为搜索请求body中的全部内容提供了setter。match_all
查询添加到SearchSourceBuilder
。SearchSourceBuilder
添加到SeachRequest
。咱们先来看一下SearchRequest
的一些可选参数:数组
SearchRequest searchRequest = new SearchRequest("posts"); searchRequest.types("doc");
还有一些其余有趣的可选参数:异步
searchRequest.routing("routing");
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
IndicesOptions
控制如何解析不可用的索引以及如何扩展通配符表达式。searchRequest.preference("_local");
控制搜索行为的大多数选项均可以在SearchSourceBuilder
上设置,它包含或多或少与Rest API的搜索请求body中等效的选项。ide
如下是一些常见选项的几个示例:函数
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy")); sourceBuilder.from(0); sourceBuilder.size(5); sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
SearchSourceBuilder
。QueryBuilder
。from
选项,默认为0
。size
选项,默认为10
。在此以后,只需将SearchSourceBuilder
添加到SearchRequest
:post
SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("posts"); searchRequest.source(sourceBuilder);
使用QueryBuilder
对象建立搜索查询,QueryBuilder存在对于Elasticsearch的查询DSL支持的每种搜索查询类型。性能
可使用其构造函数建立QueryBuilder
:fetch
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy");
建立后,QueryBuilder
对象提供了配置其建立的搜索查询选项的方法:ui
matchQueryBuilder.fuzziness(Fuzziness.AUTO); matchQueryBuilder.prefixLength(3); matchQueryBuilder.maxExpansions(10);
也可使用QueryBuilders
实用程序类建立QueryBuilder
对象,此类提供了可用于使用流畅的编程样式建立QueryBuilder
对象的辅助方法:
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy") .fuzziness(Fuzziness.AUTO) .prefixLength(3) .maxExpansions(10);
不管用于建立它的方法是什么,都必须将QueryBuilder
对象添加到SearchSourceBuilder
,以下所示:
searchSourceBuilder.query(matchQueryBuilder);
构建查询页面提供了全部可用的搜索查询的列表及其相应的QueryBuilder
对象和QueryBuilders
辅助方法。
SearchSourceBuilder
容许添加一个或多个SortBuilder
实例,有四种特殊的实现(Field-,Score-,GeoDistance-和ScriptSortBuilder)。
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC));
_score
降序排序(默认值)。_id
字段进行升序排序。默认状况下,搜索请求会返回文档_source
的内容,但与Rest API中的内容同样,你能够覆盖此行为,例如,你能够彻底关闭_source
检索:
sourceBuilder.fetchSource(false);
该方法还接受一个或多个通配符模式的数组,以控制以更精细的方式包含或排除哪些字段:
String[] includeFields = new String[] {"title", "user", "innerObject.*"}; String[] excludeFields = new String[] {"_type"}; sourceBuilder.fetchSource(includeFields, excludeFields);
经过在SearchSourceBuilder
上设置HighlightBuilder
,能够实现高亮搜索结果,经过将一个或多个HighlightBuilder.Field
实例添加到HighlightBuilder
,能够为每一个字段定义不一样的高亮行为。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); HighlightBuilder highlightBuilder = new HighlightBuilder(); HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("title"); highlightTitle.highlighterType("unified"); highlightBuilder.field(highlightTitle); HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user"); highlightBuilder.field(highlightUser); searchSourceBuilder.highlighter(highlightBuilder);
HighlightBuilder
。title
字段建立字段高光色。Rest API文档中有许多选项须要详细说明,Rest API参数(例如pre_tags
)一般由具备类似名称的setter更改而来(例如#preTags(String ...)
)。
稍后能够从SearchResponse
中检索高亮的文本片断。
能够经过先建立适当的AggregationBuilder
而后在SearchSourceBuilder
上设置聚合来将聚合添加到搜索中,在如下示例中,咱们在公司名称上建立terms
聚合 ,使用子聚合在公司员工平均年龄上:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company") .field("company.keyword"); aggregation.subAggregation(AggregationBuilders.avg("average_age") .field("age")); searchSourceBuilder.aggregation(aggregation);
构建聚合页面提供了全部可用的聚合的列表及其对应的AggregationBuilder
对象和AggregationBuilders
辅助方法。
稍后咱们将看到如何访问SearchResponse
中的聚合。
要向搜索请求添加建议,请使用从SuggestBuilders
工厂类中可轻松访问的SuggestionBuilder
的实现之一,Suggestion构建器须要添加到顶级SuggestBuilder
,它自己能够在SearchSourceBuilder
上设置。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); SuggestionBuilder termSuggestionBuilder = SuggestBuilders.termSuggestion("user").text("kmichy"); SuggestBuilder suggestBuilder = new SuggestBuilder(); suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder); searchSourceBuilder.suggest(suggestBuilder);
user
字段和文本kmichy
建立一个新的TermSuggestionBuilder
。suggest_user
。咱们稍后将看到如何从SearchResponse
中检索suggestion。
分析API可用于分析特定搜索请求的查询和聚合的执行状况,为了使用它,必须在SearchSourceBuilder
上将profile
标志设置为true
:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.profile(true);
执行SearchRequest
后,相应的SearchResponse
将包含分析结果。
如下列方式执行SearchRequest
时,客户端在继续执行代码以前等待返回SearchResponse
:
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
执行SearchRequest
也能够以异步方式完成,以便客户端能够直接返回,用户须要经过将请求和监听器传递给异步搜索方法来指定响应或潜在的故障如何处理:
client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener);
SearchRequest
和执行完成时要使用的ActionListener
。异步方法不会阻塞而且当即返回,完成后,若是执行成功完成则使用onResponse
方法回调ActionListener
,若是失败则使用onFailure
方法。
SearchResponse
的典型监听器以下所示:
ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() { @Override public void onResponse(SearchResponse searchResponse) { } @Override public void onFailure(Exception e) { } };
onResponse
:执行成功完成时调用。onFailure
:在整个SearchRequest
失败时调用。经过执行搜索返回的SearchResponse
提供有关搜索执行自己以及对返回文档的访问的详细信息,首先,有关于请求执行自己的有用信息,例如HTTP状态码,执行时间或请求是提早终止仍是超时:
RestStatus status = searchResponse.status(); TimeValue took = searchResponse.getTook(); Boolean terminatedEarly = searchResponse.isTerminatedEarly(); boolean timedOut = searchResponse.isTimedOut();
其次,响应还经过提供有关搜索影响的碎片总数以及成功与不成功碎片的统计信息的碎片级别执行的信息,能够经过在ShardSearchFailures
上迭代数组来处理可能的失败,以下例所示:
int totalShards = searchResponse.getTotalShards(); int successfulShards = searchResponse.getSuccessfulShards(); int failedShards = searchResponse.getFailedShards(); for (ShardSearchFailure failure : searchResponse.getShardFailures()) { // failures should be handled here }
要访问返回的文档,咱们须要先获取响应中包含的SearchHits
:
SearchHits hits = searchResponse.getHits();
SearchHits
提供有关全部匹配的全局信息,例如总命中数或最高分数:
long totalHits = hits.getTotalHits(); float maxScore = hits.getMaxScore();
嵌套在SearchHits
中的是能够迭代的单个搜索结果:
SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) { // do something with the SearchHit }
SearchHit
提供对每一个搜索命中的索引、类型、docId和分数等基本信息的访问:
String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId(); float score = hit.getScore();
此外,它还容许你以简单的JSON-String或键/值对映射的形式返回文档源,在此映射中,常规字段由字段名称键控并包含字段值,多值字段做为对象列表返回,嵌套对象做为另外一个键/值映射返回,这些案例须要相应地进行投射:
String sourceAsString = hit.getSourceAsString(); Map<String, Object> sourceAsMap = hit.getSourceAsMap(); String documentTitle = (String) sourceAsMap.get("title"); List<Object> users = (List<Object>) sourceAsMap.get("user"); Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject");
若是须要,能够从结果中的每一个SearchHit
检索高亮的文本片断,命中对象提供对HighlightField
实例的字段名称映射的访问,每一个实例包含一个或多个高亮的文本片断:
SearchHits hits = searchResponse.getHits(); for (SearchHit hit : hits.getHits()) { Map<String, HighlightField> highlightFields = hit.getHighlightFields(); HighlightField highlight = highlightFields.get("title"); Text[] fragments = highlight.fragments(); String fragmentString = fragments[0].string(); }
title
字段的高亮。能够从SearchResponse
检索聚合,先获取聚合树的根,Aggregations
对象,而后按名称获取聚合。
Aggregations aggregations = searchResponse.getAggregations(); Terms byCompanyAggregation = aggregations.get("by_company"); Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic"); Avg averageAge = elasticBucket.getAggregations().get("average_age"); double avg = averageAge.getValue();
by_company
的terms
聚合。Elastic
键入的桶。average_age
子聚合。请注意,若是按名称访问聚合,则须要根据所请求的聚合类型指定聚合接口,不然将引起ClassCastException
:
Range range = aggregations.get("by_company");
terms
聚合,但咱们尝试将其做为range
聚合进行检索。还能够将全部聚合做为由聚合名称键入的映射进行访问,在这种状况下,须要显式地进行到正确聚合接口的转换:
Map<String, Aggregation> aggregationMap = aggregations.getAsMap(); Terms companyAggregation = (Terms) aggregationMap.get("by_company");
还有一些getter将全部顶级聚合做为列表返回:
List<Aggregation> aggregationList = aggregations.asList();
最后但并不是最不重要的是,你能够迭代全部聚合,而后例如决定如何根据类型进一步处理它们:
for (Aggregation agg : aggregations) { String type = agg.getType(); if (type.equals(TermsAggregationBuilder.NAME)) { Bucket elasticBucket = ((Terms) agg).getBucketByKey("Elastic"); long numberOfDocs = elasticBucket.getDocCount(); } }
要从SearchResponse
获取suggestions,请使用Suggest
对象做为入口点,而后检索嵌套的suggestion对象:
Suggest suggest = searchResponse.getSuggest(); TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user"); for (TermSuggestion.Entry entry : termSuggestion.getEntries()) { for (TermSuggestion.Entry.Option option : entry) { String suggestText = option.getText().string(); } }
Suggest
类访问suggestions。TermSuggestion
),不然抛出ClassCastException
。使用getProfileResults()
方法从SearchResponse
检索分析结果,此方法返回包含SearchSquest
执行中涉及的每一个碎片的ProfileShardResult
对象的Map
,ProfileShardResult
使用惟一标识分析结果对应的碎片的键存储在Map
中。
下面是一个示例代码,显示如何迭代每一个碎片的全部分析结果:
Map<String, ProfileShardResult> profilingResults = searchResponse.getProfileResults(); for (Map.Entry<String, ProfileShardResult> profilingResult : profilingResults.entrySet()) { String key = profilingResult.getKey(); ProfileShardResult profileShardResult = profilingResult.getValue(); }
SearchResponse
中检索ProfileShardResult
的Map
。ProfileShardResult
属于哪一个碎片的键。ProfileShardResult
。ProfileShardResult
对象自己包含一个或多个查询分析结果,每一个查询针对基础Lucene索引执行:
List<QueryProfileShardResult> queryProfileShardResults = profileShardResult.getQueryProfileResults(); for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) { }
QueryProfileShardResult
的列表。QueryProfileShardResult
。每一个QueryProfileShardResult
都提供对详细查询树执行的访问,做为ProfileResult
对象列表返回:
for (ProfileResult profileResult : queryProfileResult.getQueryResults()) { String queryName = profileResult.getQueryName(); long queryTimeInMillis = profileResult.getTime(); List<ProfileResult> profiledChildren = profileResult.getProfiledChildren(); }
Rest API文档包含有关分析查询的更多信息以及查询分析信息的说明。
QueryProfileShardResult
还能够访问Lucene收集器的分析信息:
CollectorResult collectorResult = queryProfileResult.getCollectorResult(); String collectorName = collectorResult.getName(); Long collectorTimeInMillis = collectorResult.getTime(); List<CollectorResult> profiledChildren = collectorResult.getProfiledChildren();
Rest API文档包含有关Lucene收集器的分析信息的更多信息。
以与查询树执行很是相似的方式,QueryProfileShardResult
对象提供对详细聚合树执行的访问:
AggregationProfileShardResult aggsProfileResults = profileShardResult.getAggregationProfileResults(); for (ProfileResult profileResult : aggsProfileResults.getProfileResults()) { String aggName = profileResult.getQueryName(); long aggTimeInMillis = profileResult.getTime(); List<ProfileResult> profiledChildren = profileResult.getProfiledChildren(); }
AggregationProfileShardResult
。Rest API文档包含有关分析聚合的更多信息。