High Level Rest Client 搜索响应对象介绍

2021-04-23 0 By admin

当Java 开发过程中使用High Level Rest Client(高级别Rest客户端)操作 Elasticsearch 集群时,其搜索响应对象 SearchResponse 和响应数据的解析过程介绍。

十二、SearchResponse 搜索响应对象

执行搜索返回的 SearchResponse 提供有关搜索执行本身的详细信息,以及对返回的文档的访问详细信息。

12.1、查询执行本身情况

首先,有关请求执行本身的有用信息,如HTTP状态代码,执行时间或请求是否提前终止或超时:

RestStatus status = searchResponse.status();
TimeValue took = searchResponse.getTook();
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut();

12.2、查询执行影响分片信息

其次,响应还通过提供有关受搜索影响的分片总数的统计数据,来提供有关分片级别的执行的信息,以及成功的和不成功的分片。也可以通过在以下示例中 ShardsearchFailures 迭代可能的故障:

int totalShards = searchResponse.getTotalShards();
int successfulShards = searchResponse.getSuccessfulShards();
int failedShards = searchResponse.getFailedShards();
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
    // failures should be handled here
}

十三、Retrieving SearchHits 检索SearchHits

要访问返回的文档,我们需要首先获得响应中包含的 SearchHits:
SearchHits hits = searchResponse.getHits();
SearchHits提供关于所有点击的全局信息,比如总点击数或最大得分:

TotalHits totalHits = hits.getTotalHits();
// 点击总数,必须在totalHits.relation
long numHits = totalHits.value;
// 命中数是否准确(等于)或总数的下限(大于或等于)
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();
tring 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");

十四、Retrieving Highlighting 检索高亮

如果需要,可以从结果中的每个 SearchHit 检索突出显示的文本片段。hit对象提供了从字段名到 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();
}

十五、Retrieving Aggregations 检索聚合

通过首先获取聚合树的根,即Aggregations对象,然后通过名称获取聚合,可以从SearchResponse检索聚合。

Aggregations aggregations = searchResponse.getAggregations();
Terms byCompanyAggregation = aggregations.get("by_company"); //得到by_company聚合
Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic"); //得到Elastic对应的Bucket
Avg averageAge = elasticBucket.getAggregations().get("average_age"); //从该bucket获取average_age子聚合
double avg = averageAge.getValue();

注意,如果按名称访问聚合,需要根据请求的聚合类型指定聚合接口,否则会抛出ClassCastException:
Range range = aggregations.get("by_company");
会抛出一个异常,因为“by_company”是一个术语聚合,但我们试图将其检索为一个范围聚合。

还可以将所有聚合作为映射访问,映射由聚合名称作为键。在这种情况下,需要显式地转换到适当的聚合接口:

Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
Terms companyAggregation = (Terms) aggregationMap.get("by_company");

还可以返回所有顶级的聚合为一个列表:

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

十六、Retrieving Suggestion 检索建议

要从 SearchResponse 获取建议,使用 Suggest 对象作为入口点,然后检索嵌套的建议对象:

Suggest suggest = searchResponse.getSuggest(); //使用Suggest类来访问建议
TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user"); 
//可以通过名称检索建议。您需要将它们分配给建议类的正确类型(这里是TermSuggestion),否则将抛出ClassCastException
for (TermSuggestion.Entry entry : termSuggestion.getEntries()) { //迭代建议条目
    for (TermSuggestion.Entry.Option option : entry) { //遍历一个条目中的选项
        String suggestText = option.getText().string();
    }
}

十七、Retrieving Profiling Results 检索分析结果

使用 getProfileResults() 方法从 SearchResponse 检索分析结果(Profiling results )。此方法为 SearchRequest 执行中涉及的每个分片返回一个包含 ProfileShardResult 对象的映射。ProfileShardResult 使用唯一标识配置文件结果所对应的分片的键存储在映射中。

下面的示例代码演示了如何遍历每个碎片的所有分析结果:

Map<String, ProfileShardResult> profilingResults =
        searchResponse.getProfileResults(); //从SearchResponse检索ProfileShardResult的地图
for (Map.Entry<String, ProfileShardResult> profilingResult : profilingResults.entrySet()) { 
//如果键是已知的,那么可以通过shard的键检索分析结果,否则遍历所有分析结果可能更简单
    String key = profilingResult.getKey(); //检索标识ProfileShardResult属于哪个碎片的键
    ProfileShardResult profileShardResult = profilingResult.getValue(); //检索给定碎片的ProfileShardResult
}

ProfileShardResult 对象本身包含一个或多个查询配置文件结果,每个查询一个针对底层Lucene索引执行:

List<QueryProfileShardResult> queryProfileShardResults =
        profileShardResult.getQueryProfileResults(); //检索QueryProfileShardResult的列表
for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) {
//遍历每个QueryProfileShardResult
}

每个QueryProfileShardResult都允许访问详细的查询树执行,以ProfileResult对象列表的形式返回:

for (ProfileResult profileResult : queryProfileResult.getQueryResults()) { 
//遍历配置文件结果
    String queryName = profileResult.getQueryName(); //检索Lucene查询的名称
    long queryTimeInMillis = profileResult.getTime(); 
	//检索在millis中执行Lucene查询所花费的时间
    List<ProfileResult> profiledChildren = profileResult.getProfiledChildren(); 
	//检索子查询的概要结果(如果有的话)
}

Rest API文档包含关于分析查询的更多信息,其中描述了查询分析信息。
QueryProfileShardResult 还为Lucene收集器提供了对概要信息的访问:

CollectorResult collectorResult = queryProfileResult.getCollectorResult();  
//检索Lucene收集器的分析结果
String collectorName = collectorResult.getName();
//检索Lucene收集器的名称
Long collectorTimeInMillis = collectorResult.getTime();
//检索在millis中执行Lucene收集器所花费的时间
List<CollectorResult> profiledChildren = collectorResult.getProfiledChildren(); 
//检索子收集器的配置文件结果(如果有)

Rest API文档包含关于Lucene收集器的分析信息的更多信息。看到分析查询。
QueryProfileShardResult对象以与查询树执行非常相似的方式访问详细的聚合树执行:

AggregationProfileShardResult aggsProfileResults =
        profileShardResult.getAggregationProfileResults(); 
		//检索AggregationProfileShardResult
for (ProfileResult profileResult : aggsProfileResults.getProfileResults()) { 
//遍历聚合配置文件结果
    String aggName = profileResult.getQueryName(); 
	//检索聚合的类型(对应于用于执行聚合的Java类)
    long aggTimeInMillis = profileResult.getTime(); 
	//检索在millis中执行Lucene收集器所花费的时间
    List<ProfileResult> profiledChildren = profileResult.getProfiledChildren(); 
	//检索子聚合的配置文件结果(如果有的话)
}