我正在尝试使用Java高级REST客户端执行Elasticsearch查询。主要目标是为我分组结果。 这是数据:
"hits" : [
{
"_index" : "my_index",
"_type" : "object",
"_id" : "X4sSPmYB62YwufswHQbx",
"_score" : 1.0,
"_source" : {
"objId" : "1",
"stepId" : "step_one",
"status" : "RUNNING",
"timestamp" : 1515974400
}
},
{
"_index" : "my_index",
"_type" : "object",
"_id" : "15QRP2YB62YwufswAApl",
"_score" : 1.0,
"_source" : {
"objId" : "1",
"stepId" : "step_one",
"status" : "DONE",
"timestamp" : 1516406400
}
},
{
"_index" : "my_index",
"_type" : "object",
"_id" : "QpMOP2YB62YwufswrfYn",
"_score" : 1.0,
"_source" : {
"objId" : "1",
"stepId" : "step_two",
"status" : "RUNNING",
"timestamp" : 1516492800
}
},
{
"_index" : "my_index",
"_type" : "object",
"_id" : "VZMPP2YB62YwufswJ_r0",
"_score" : 1.0,
"_source" : {
"objId" : "1",
"stepId" : "step_two",
"status" : "DONE",
"timestamp" : 1517356800
}
},
{
"_index" : "my_index",
"_type" : "object",
"_id" : "XZMPP2YB62YwufswQfrc",
"_score" : 1.0,
"_source" : {
"objId" : "2",
"stepId" : "step_one",
"status" : "DONE",
"timestamp" : 1517788800
}
}
}
]
例如对于objId = 1,我希望检索类似的内容:
{
"objId" : "1",
"stepId" : "step_one",
"status" : "DONE",
"timestamp" : 1516406400
},
{
"objId" : "1",
"stepId" : "step_two",
"status" : "DONE",
"timestamp" : 1517356800
}
现在我有了这个Java方法:
private List<MyObject> search(String objId) {
MatchPhraseQueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("objId", objId);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder);
searchSourceBuilder.size(1000);
SearchRequest searchRequest = new SearchRequest("my_index");
searchRequest.types("object");
searchRequest.source(searchSourceBuilder);
try {
SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
return Arrays.stream(searchResponse.getHits().getHits())
.map(this::toMyObject)
.collect(toList());
} catch (IOException ex) {
log.error("Error retrieving records from elasticsearch. {} ", ex);
}
return new ArrayList<>();
}
但是此方法仅返回objId找到的对象列表。
我的问题是: 是否可以通过 objId 值查找对象,而不是通过 stepId 对其进行分组,最后通过最新的 timestamp 过滤结果?
答案 0 :(得分:0)
以下是我发现的问题的答案:
private List<MyObject> search(String objId) {
try {
SearchResponse searchResponse = esRestClient.search(new SearchRequest("my_index")
.source(new SearchSourceBuilder()
.query(QueryBuilders.matchPhraseQuery("objId", objId))
.size(0)
.aggregation(
AggregationBuilders.terms("by_stepId").field("stepId.keyword")
.subAggregation(AggregationBuilders.topHits("by_timestamp")
.sort("timestamp", SortOrder.DESC)
.size(1)
)
)
)
.types("object")
);
Terms terms = searchResponse.getAggregations().get("by_stepId");
return terms.getBuckets().stream()
.map(MultiBucketsAggregation.Bucket::getAggregations)
.flatMap(buckets -> buckets.asList().stream())
.map(aggregations -> (ParsedTopHits) aggregations)
.flatMap(topHits -> Arrays.stream(topHits.getHits().getHits()))
.map(this::toMyObject)
.collect(toList());
} catch (IOException ex) {
log.error("Error retrieving records from elasticsearch. {} ", ex);
}
return new ArrayList<>();
}