SearchRequest可用于搜索文档,聚合文档,还有搜索结果的高亮显示
SearchRequest的最基础的形式
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchRequest searchRequest = new SearchRequest("posts");
searchRequest.routing("routing");
Setting IndicesOptions controls how unavailable indices are resolved and how wildcard expressions are expanded
设置IndicesOptions控制如何解决不可用的索引以及如何扩展通配符表达式
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
使用首选项参数,例如,执行搜索以偏爱本地碎片。默认设置是随机分片。
searchRequest.preference("_local");
许多控制搜索的行为都可以通过SearchSourceBuilder来设定,该选项或多或少包含与Rest API的搜索请求正文中的选项等效的选项。
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
sourceBuilder.from(0);
sourceBuilder.size(5);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
搜索条件构造好了之后,将SearchSourceBuilder假如到SearchRequest中即可
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("posts");
searchRequest.source(sourceBuilder);
需要通过QueryBuilder兑现过来创建搜索条件,QueryBuilder支持所有的Elasticsearch QueryDSL.
可以通过QueryBuilder构造器创建QueryBuilder
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy");
一旦创建完成之后之后,QueryBuilder对象将提供方法来配置其创建的搜索查询的选项:
matchQueryBuilder.fuzziness(Fuzziness.AUTO);
matchQueryBuilder.prefixLength(3);
matchQueryBuilder.maxExpansions(10);
也可以通过流式编程创建QueryBuilder
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
.fuzziness(Fuzziness.AUTO)
.prefixLength(3)
.maxExpansions(10);
不管你用什么方式创建QueryBuilder,都必须将其加入到searchSourceBuilder中。
在 Building Queries页面给出了可用的所有QueryBuilder方法。
SearchSourceBuilder允许添加一个或者多个SortBuilder排序实例,有四种具体的排序实现
Field score GeoDistance ScriptSortBuilder
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
sourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.ASC));
默认的情况下,搜索请求返回文档中的_source,你也可以关掉这一选项。
sourceBuilder.fetchSource(false);
这个方法也可以过滤掉我们不想要的fields
String[] includeFields = new String[] {"title", "innerObject.*"};
String[] excludeFields = new String[] {"user"};
sourceBuilder.fetchSource(includeFields, excludeFields);
高亮搜索的结果可以通过在SearchSourceBuilder设置HighlightBuilder来实现。不同的高亮表现可以通过设置不同的HighlightBuilder.Field来实现
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);
可以通过在初始的创建合适的AggregationBuilder并将其加入到SearchSourceBuilder来实现聚合查询。
在下面的例子中我们创建了以company name 为组的聚合器,同时还聚合了员工平均工资的操作。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company")
.field("company.keyword");
aggregation.subAggregation(AggregationBuilders.avg("average_age")
.field("age"));
searchSourceBuilder.aggregation(aggregation);
更多聚合操作 在 Building Aggregations 页
要将“建议”添加到搜索请求中,请使用SuggestionBuilder可从SuggestBuilders工厂类轻松访问的实现之一。建议建设者需要添加到顶层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);
Profile API 可以分析查询请求的执行过程也可以聚合特定的查询结果,如果想要使用它,就必须将SearchSourceBuilde上的分析标记打开
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.profile(true);
一旦查询请求被执行了,那么在查询响应中就会有查询请求分析的结果
在SearchResponse 不仅返回了需要搜索的文档,同样也服务器也返回了本次搜索的执行详情,类似于HTTP响应头,状态码。
本次查询请求的信息 状态,耗时,是否超时
RestStatus status = searchResponse.status();
TimeValue took = searchResponse.getTook();
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut();
第二,响应中同样也提供了关于分片的信息,比如本次查询请求影响了多少个分片,成功分片,失败分片。
int totalShards = searchResponse.getTotalShards();
int successfulShards = searchResponse.getSuccessfulShards();
int failedShards = searchResponse.getFailedShards();
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
// failures should be handled here
}
为了得到返回的文档,我们需要首先得到response中的SearchHits对象。
SearchHits hits = searchResponse.getHits();
SearchHits 提供了命中文档的一些全局信息,比如命中的文档数,最大得分
TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation = totalHits.relation;
float maxScore = hits.getMaxScore();
嵌套在中的SearchHits是可以迭代的各个搜索结果:
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// do something with the SearchHit
}
SearchHit提供了搜索索引的基本信息,如索引,文档id,得分
String index = hit.getIndex();
String id = hit.getId();
float score = hit.getScore();
此外,SearchHit可以让你以Json 字符串的形式或者map 的形式获取到文档source 内容,在map里面中,常规字段由字段名称键入并包含字段值。多值字段以对象列表的形式返回,嵌套对象以另一个键/值映射的形式返回。这些情况需要相应地强制转换:
String sourceAsString = hit.getSourceAsString();
Map sourceAsMap = hit.getSourceAsMap();
String documentTitle = (String) sourceAsMap.get("title");
List
如果需要,可以通过结果中的每个SearchHit来截取文本片段的高亮显示。
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits.getHits()) {
Map highlightFields = hit.getHighlightFields();
HighlightField highlight = highlightFields.get("title");
Text[] fragments = highlight.fragments();
String fragmentString = fragments[0].string();
}
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();
请注意,如果按名称访问聚合,则需要根据请求的聚合类型指定聚合接口,否则ClassCastException将抛出a:
Range range = aggregations.get("by_company");
也可以将所有聚合作为以聚合名称作为关键字的映射来访问。在这种情况下,必须明确地强制转换为正确的聚合接口:
Map aggregationMap = aggregations.getAsMap();
Terms companyAggregation = (Terms) aggregationMap.get("by_company");
还有一些getter会将所有顶级聚合返回为列表:
List 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,请使用Suggest对象作为入口点,然后检索嵌套的建议对象:
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();
}
}
通过searchResponse的getProfileResults可以得到分析结果,返回Map
Map profilingResults =
searchResponse.getProfileResults();
for (Map.Entry profilingResult : profilingResults.entrySet()) {
String key = profilingResult.getKey();
ProfileShardResult profileShardResult = profilingResult.getValue();
}
所述ProfileShardResult对象本身包含一个或多个查询简档的结果,一个用于抵靠底层Lucene索引执行的每个查询:
List queryProfileShardResults =
profileShardResult.getQueryProfileResults();
for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) {
}
每个都QueryProfileShardResult可以访问详细的查询树执行,并以ProfileResult对象列表的形式返回 :
for (ProfileResult profileResult : queryProfileResult.getQueryResults()) {
String queryName = profileResult.getQueryName();
long queryTimeInMillis = profileResult.getTime();
List profiledChildren = profileResult.getProfiledChildren();
}
Rest API文档包含有关性能分析查询的更多信息,并带有查询性能分析信息的描述。
该QueryProfileShardResult还可以访问了Lucene的收集器的分析信息:
CollectorResult collectorResult = queryProfileResult.getCollectorResult();
String collectorName = collectorResult.getName();
Long collectorTimeInMillis = collectorResult.getTime();
List 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 profiledChildren = profileResult.getProfiledChildren();
}