使用 spring 数据 elasticsearch 的特定字段的文档、最小值和最大值
Document, Min and Max for specific field with spring data elasticsearch
我正在使用 Spring Data ElasticSearch 并尝试获取其中一个字段具有最小值和最大值的不同文档。我还需要与最大值关联的文档。
基于我发现的一些例子和一些修补,我想出了这个,但我不太确定从这里去哪里或者这是否会实现我正在寻找的东西。
TermsBuilder termBuilder = AggregationBuilders.terms("check_id");
MaxBuilder maxBuilder = AggregationBuilders.max("exec_time_epoch");
MinBuilder minBuilder = AggregationBuilders.min("exec_time_epoch");
termBuilder.subAggregation(maxBuilder);
termBuilder.subAggregation(minBuilder);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.addAggregation(termBuilder)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
我不确定如何从中获取最小值和最大值或与最大值关联的文档。
更新:
在你的帮助下,我找到了完成这项工作的方法。这是我的完整代码,以防将来对某人有所帮助。
public List<CamAlertDetail> findOldestAndNewest(String category) {
TermsBuilder termBuilder = AggregationBuilders.terms("agg_terms").field("check_id");
TopHitsBuilder topHitsBuilder = AggregationBuilders.topHits("maxDoc")
.setSize(1)
.addSort("exec_time_epoch", SortOrder.DESC);
TopHitsBuilder topHitsBuilder2 = AggregationBuilders.topHits("minDoc")
.setSize(1)
.addSort("exec_time_epoch", SortOrder.ASC);
termBuilder.subAggregation(topHitsBuilder);
termBuilder.subAggregation(topHitsBuilder2);
QueryBuilder queryBuilder;
if (category != null) {
queryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("categories", category));
} else {
queryBuilder = matchAllQuery();
}
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withIndices("caam-results")
.addAggregation(termBuilder)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
Terms terms = aggregations.get("agg_terms");
List<CamAlertDetail> list = new ArrayList<>();
for (Terms.Bucket bucket : terms.getBuckets()) {
TopHits min = bucket.getAggregations().get("minDoc");
TopHits max = bucket.getAggregations().get("maxDoc");
CamAlertDetail detail = new CamAlertDetail();
detail.setOldest(createAlertFromSearchHit(min.getHits().getAt(0)));
detail.setNewest(createAlertFromSearchHit(max.getHits().getAt(0)));
list.add(detail);
}
return list;
}
private CamAlert createAlertFromSearchHit(SearchHit hit) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(hit.sourceAsString(), CamAlert.class);
} catch (IOException e) {
log.error("Error Converting json to cam alert.", e);
return null;
}
}
你的方向是正确的,你只需要得到一个具有最大 exec_time_epoch
值的文档,为此你可以在 [=13= 中添加另一个 top_hits
sub-aggregation ] check_id
的聚合,将单个文档按 exec_time_epoch
.
的降序排列
TermsBuilder termBuilder = AggregationBuilders.terms("check_id");
MaxBuilder maxBuilder = AggregationBuilders.max("exec_time_epoch");
MinBuilder minBuilder = AggregationBuilders.min("exec_time_epoch");
termBuilder.subAggregation(maxBuilder);
termBuilder.subAggregation(minBuilder);
// ADD THIS: add another top_hits sub-aggregation which
// - takes a single document
// - sorted by exec_time_epoch desc
TopHitsBuilder topHitsBuilder = AggregationBuilders.topHits("maxDoc")
.setSize(1)
.addSort("exec_time_epoch", SortOrder.DESC);
termBuilder.subAggregation(topHitsBuilder);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.addAggregation(termBuilder)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
我正在使用 Spring Data ElasticSearch 并尝试获取其中一个字段具有最小值和最大值的不同文档。我还需要与最大值关联的文档。
基于我发现的一些例子和一些修补,我想出了这个,但我不太确定从这里去哪里或者这是否会实现我正在寻找的东西。
TermsBuilder termBuilder = AggregationBuilders.terms("check_id");
MaxBuilder maxBuilder = AggregationBuilders.max("exec_time_epoch");
MinBuilder minBuilder = AggregationBuilders.min("exec_time_epoch");
termBuilder.subAggregation(maxBuilder);
termBuilder.subAggregation(minBuilder);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.addAggregation(termBuilder)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
我不确定如何从中获取最小值和最大值或与最大值关联的文档。
更新:
在你的帮助下,我找到了完成这项工作的方法。这是我的完整代码,以防将来对某人有所帮助。
public List<CamAlertDetail> findOldestAndNewest(String category) {
TermsBuilder termBuilder = AggregationBuilders.terms("agg_terms").field("check_id");
TopHitsBuilder topHitsBuilder = AggregationBuilders.topHits("maxDoc")
.setSize(1)
.addSort("exec_time_epoch", SortOrder.DESC);
TopHitsBuilder topHitsBuilder2 = AggregationBuilders.topHits("minDoc")
.setSize(1)
.addSort("exec_time_epoch", SortOrder.ASC);
termBuilder.subAggregation(topHitsBuilder);
termBuilder.subAggregation(topHitsBuilder2);
QueryBuilder queryBuilder;
if (category != null) {
queryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("categories", category));
} else {
queryBuilder = matchAllQuery();
}
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withIndices("caam-results")
.addAggregation(termBuilder)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
Terms terms = aggregations.get("agg_terms");
List<CamAlertDetail> list = new ArrayList<>();
for (Terms.Bucket bucket : terms.getBuckets()) {
TopHits min = bucket.getAggregations().get("minDoc");
TopHits max = bucket.getAggregations().get("maxDoc");
CamAlertDetail detail = new CamAlertDetail();
detail.setOldest(createAlertFromSearchHit(min.getHits().getAt(0)));
detail.setNewest(createAlertFromSearchHit(max.getHits().getAt(0)));
list.add(detail);
}
return list;
}
private CamAlert createAlertFromSearchHit(SearchHit hit) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(hit.sourceAsString(), CamAlert.class);
} catch (IOException e) {
log.error("Error Converting json to cam alert.", e);
return null;
}
}
你的方向是正确的,你只需要得到一个具有最大 exec_time_epoch
值的文档,为此你可以在 [=13= 中添加另一个 top_hits
sub-aggregation ] check_id
的聚合,将单个文档按 exec_time_epoch
.
TermsBuilder termBuilder = AggregationBuilders.terms("check_id");
MaxBuilder maxBuilder = AggregationBuilders.max("exec_time_epoch");
MinBuilder minBuilder = AggregationBuilders.min("exec_time_epoch");
termBuilder.subAggregation(maxBuilder);
termBuilder.subAggregation(minBuilder);
// ADD THIS: add another top_hits sub-aggregation which
// - takes a single document
// - sorted by exec_time_epoch desc
TopHitsBuilder topHitsBuilder = AggregationBuilders.topHits("maxDoc")
.setSize(1)
.addSort("exec_time_epoch", SortOrder.DESC);
termBuilder.subAggregation(topHitsBuilder);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.addAggregation(termBuilder)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});