Итак, я смог реплицировать запрос elasticsearch по своему желанию на Java с помощью restclient высокого уровня elasticsearch. Проблема в том, что я не могу получить нужные значения. Прежде чем я дам код, я хочу обратиться к общей цели на случай, если есть гораздо более простое решение (похоже, это не должно быть так сложно).
Общая цель: получить количество документов, в которых «посещено» == истина для каждого уникального значения в поле «рекомендатель».
Мой текущий статус: мне удалось написать запрос с желаемым выводом в kibana / elasticsearch, но когда я реплицирую этот запрос на Java, я не могу получить доступ к нужным мне данным. (Проверено с помощью searchRequest.source (). ToString ()).
Вот запрос:
{
"aggs":{
"recommenderIDs": {
"terms": {
"field": "recommender"
},
"aggs": {
"visit_stats": {
"filters": {
"filters": {
"visited": {
"match":{
"visited": true
}
}
}
}
}
}
}
}
}
И это то, что у меня есть в моем java-коде:
// ...
SearchRequest searchRequest = new SearchRequest(INDEX_REC_RECOMMENDATIONS);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
String aggregationName = "recommenderId";
String filterName = "wasVisited";
TermsAggregationBuilder aggQuery = AggregationBuilders
.terms(aggregationName)
.field(RecommendationRepoFieldNames.RECOMMENDER);
AggregationBuilder aggFilters = AggregationBuilders.filters(
filterName,
new FiltersAggregator.KeyedFilter(
RecommendationRepoFieldNames.RECOMMENDER,
QueryBuilders.termQuery(RecommendationRepoFieldNames.VISITED, true))
);
aggQuery.subAggregation(aggFilters);
searchSourceBuilder.aggregation(aggQuery);
searchRequest.source(searchSourceBuilder);
// System.out.println(searchRequest.source().toString());
try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
Terms byRecommenderId = aggregations.get(aggregationName);
Filters filterResponses = searchResponse.getAggregations().get(aggregationName);
// for (Filters.Bucket entry : filterResponses.getBuckets()) {
// String key = entry.getKeyAsString();
// }
for (Terms.Bucket bucket : byRecommenderId.getBuckets()) {
String bucketKey = bucket.getKeyAsString();
long totalDocs = bucket.getDocCount();
Aggregation visitedDocs = bucket.getAggregations().get(filterName);
//long visitedDocsCount = visitedDocs.getValue();
System.out.println();
}
} catch (IOException e) { //...
Я возился с этим весь день и не могу добиться никакого прогресса. Это особенно расстраивает, потому что я могу видеть количество документов для каждой корзины рекомендаций, когда я отлаживаю в своей среде IDE, но я понятия не имею, как получить к ней доступ. Я понимаю, что существует около 180 классов, расширяющих агрегирование, и я пробовал несколько, но каждый раз терпел неудачу.
Кроме того, если вы знаете какой-либо достойный ресурс для клиента высокого уровня rest elasticsearch java, пожалуйста, дайте мне знать. Спасибо!
--------- РЕДАКТИРОВАТЬ 5/4/21 -------------
Пример вывода от elasticsearch:
// searchResponse (documents returned have been truncated to show only part we are interested in)
"aggregations": {
"sterms#recommenderId": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "AdjacentActivityRecommender",
"doc_count": 3,
"filters#wasVisited": {
"buckets": {
"recommender": {
"doc_count": 2
}
}
}
},
{
"key": "DefaultProfileDBRecommender",
"doc_count": 2,
"filters#wasVisited": {
"buckets": {
"recommender": {
"doc_count": 2
}
}
}
},
{
"key": "PSTR_SC_DI",
"doc_count": 2,
"filters#wasVisited": {
"buckets": {
"recommender": {
"doc_count": 1
}
}
}
},
{
"key": "SignificantCategories",
"doc_count": 2,
"filters#wasVisited": {
"buckets": {
"recommender": {
"doc_count": 2
}
}
}
}
]
}
}
searchResponse.getAggregations () затем сохраняется в агрегаты. В конце концов, мы можем перебирать сегменты для каждого идентификатора RecommenderID, но я никогда не могу войти в агрегаты внутри каждого контейнера, что мне и нужно сделать.