Клиент Elasticsearch Java SearchResponse не может проанализировать результаты агрегации. Я наткнулся на статьи онлайн, которые предлагают добавлять типы агрегации с префиксом к ключам. Я добавил то, что, по моему мнению, применимо в моем случае использования, такое как «sterms # and sum #», но я не могу понять, какой тип применяется к основному фильтру (ключ: «matched» в моем случае). Я ожидаю, что объект buckets будет заполнен, но в настоящее время он возвращается в виде пустого массива, несмотря на ответ агрегаций, содержащихasticsearch.
Примечание. Это необходимо для модульного тестирования.
Json ответ:
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 75,
"successful": 75,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 776329,
"max_score": 0,
"hits": []
},
"aggregations": {
"sterms#matched": {
"doc_count": 15,
"sterms#id": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "mykey",
"doc_count": 15,
"sterms#manufacturerName": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "subkey",
"doc_count": 15
}
]
},
"sum#totalCars": {
"value": 214244
},
"sum#totalTrucks": {
"value": 155738
}
}
]
}
}
}
}
Парсер в Java
public static SearchResponse getSearchResponseFromJson(final String jsonFileName) {
try {
String jsonResponse = IOUtils.toString(new FileInputStream(jsonFileName));
NamedXContentRegistry registry = new NamedXContentRegistry(getDefaultNamedXContents());
XContentParser parser = JsonXContent.jsonXContent.createParser(registry, jsonResponse);
return SearchResponse.fromXContent(parser);
} catch (IOException e) {
throw new RuntimeException("Failed to get resource: " + jsonFileName, e);
} catch (Exception e) {
throw new RuntimeException(("exception " + e));
}
}
private static List<NamedXContentRegistry.Entry> getDefaultNamedXContents() {
Map<String, ContextParser<Object, ? extends Aggregation>> map = new HashMap<>();
map.put(TopHitsAggregationBuilder.NAME, (parser, content) -> ParsedTopHits.fromXContent(parser, (String) content));
map.put(StringTerms.NAME, (parser, content) -> ParsedStringTerms.fromXContent(parser, (String) content));
map.put(SumAggregationBuilder.NAME, (parser, content) -> ParsedSum.fromXContent(parser, (String) content));
//map.put(ScriptedMetricAggregationBuilder.NAME, (parser, content) -> ParsedScriptedMetric.fromXContent(parser, (String) content));
List<NamedXContentRegistry.Entry> entries = map.entrySet()
.stream()
.map(entry -> new NamedXContentRegistry.Entry(Aggregation.class,
new ParseField(entry.getKey()),
entry.getValue()))
.collect(Collectors.toList());
return entries;
}
Разобранный ответ с пустыми сегментами (ожидается, что в сегментах должны быть агрегаты totalCars и totalTrucks)
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 75,
"successful": 75,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 776329,
"max_score": 0,
"hits": []
},
"aggregations": {
"sterms#matched": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
}
}
Я не уверен, правильный ли тип фильтра для фильтра