2015-12-04 2 views
1

Я использую клиент Transport для извлечения данных из Elasticsearch.elasticsearch - Проблема с агрегациями вместе с фильтрами

Пример фрагмента кода:

String[] names = {"Stokes","Roshan"}; 
BoolQueryBuilder builder = QueryBuilders.boolQuery(); 
AggregationBuilder<?> aggregation = AggregationBuilders.filters("agg") 
    .filter(builder.filter(QueryBuilders.termsQuery("Name", "Taylor")) 
    .filter(QueryBuilders.rangeQuery("grade").lt(9.0))) 
    .subAggregation(AggregationBuilders.terms("by_year").field("year") 
    .subAggregation(AggregationBuilders.sum("sum_marks").field("marks")) 
    .subAggregation(AggregationBuilders.sum("sum_grade").field("grade"))); 
SearchResponse response = client.prepareSearch(index) 
    .setTypes(datasquareID) 
    .addAggregation(aggregation) 
    .execute().actionGet(); 
System.out.println(response.toString()); 

Я хотел вычислить сумму знаков и сумму классов с именами «Стокс» или «Рошан», чья оценка меньше 9 и группы их «год» , Пожалуйста, дайте мне знать, правильный ли мой подход или нет. Пожалуйста, дайте мне знать ваши предложения.

Документы в ES:

{ 
    "took" : 1, 
    "timed_out" : false, 
    "_shards" : { 
     "total" : 5, 
     "successful" : 5, 
     "failed" : 0 
    }, 
    "hits" : { 
     "total" : 5, 
     "max_score" : 1, 
     "hits" : [{ 
       "_index" : "bighalf", 
       "_type" : "excel", 
       "_id" : "AVE0rgXqe0-x669Gsae3", 
       "_score" : 1, 
       "_source" : { 
        "Name" : "Taylor", 
        "grade" : 9, 
        "year" : 2016, 
        "marks" : 54, 
        "subject" : "Mathematics", 
        "Gender" : "male", 
        "dob" : "13/09/2000" 
       } 
      }, { 
       "_index" : "bighalf", 
       "_type" : "excel", 
       "_id" : "AVE0rvTHe0-x669Gsae5", 
       "_score" : 1, 
       "_source" : { 
        "Name" : "Marsh", 
        "grade" : 9, 
        "year" : 2015, 
        "marks" : 70, 
        "subject" : "Mathematics", 
        "Gender" : "male", 
        "dob" : "22/11/2000" 
       } 
      }, { 
       "_index" : "bighalf", 
       "_type" : "excel", 
       "_id" : "AVE0sBbZe0-x669Gsae7", 
       "_score" : 1, 
       "_source" : { 
        "Name" : "Taylor", 
        "grade" : 3, 
        "year" : 2015, 
        "marks" : 87, 
        "subject" : "physics", 
        "Gender" : "male", 
        "dob" : "13/09/2000" 
       } 
      }, { 
       "_index" : "bighalf", 
       "_type" : "excel", 
       "_id" : "AVE0rWz4e0-x669Gsae2", 
       "_score" : 1, 
       "_source" : { 
        "Name" : "Stokes", 
        "grade" : 9, 
        "year" : 2015, 
        "marks" : 91, 
        "subject" : "Mathematics", 
        "Gender" : "male", 
        "dob" : "21/12/2000" 
       } 
      }, { 
       "_index" : "bighalf", 
       "_type" : "excel", 
       "_id" : "AVE0roT4e0-x669Gsae4", 
       "_score" : 1, 
       "_source" : { 
        "Name" : "Roshan", 
        "grade" : 9, 
        "year" : 2015, 
        "marks" : 85, 
        "subject" : "Mathematics", 
        "Gender" : "male", 
        "dob" : "12/12/2000" 
       } 
      } 
     ] 
    } 
} 

Response:

"aggregations" : { 
    "agg" : { 
     "buckets" : [{ 
       "doc_count" : 0, 
       "by_year" : { 
        "doc_count_error_upper_bound" : 0, 
        "sum_other_doc_count" : 0, 
        "buckets" : [] 
       } 
      } 
     ] 
    } 
} 

Пожалуйста, дайте мне знать решение для моего требования.

+0

ли это печать правильный результат? –

+0

Нет. На самом деле есть документы с именем «Тейлор», но я не получаю ожидаемого результата. – ravi

ответ

2

Я думаю, что проблема в вашем агрегате filters. Подводя итог, вы хотите отфильтровать агрегацию в документах «... с именами« Стокс »или« Рошан », чей класс меньше 9». Для того, чтобы сделать это

// create the sum aggregations 
SumBuilder sumMarks = AggregationBuilders.sum("sum_marks").field("marks"); 
SumBuilder sumGrades = AggregationBuilders.sum("sum_grade").field("grade"); 

// create the year aggregation + add the sum sub-aggregations 
TermsBuilder yearAgg = AggregationBuilders.terms("by_year").field("year") 
    .subAggregation(sumMarks) 
    .subAggregation(sumGrades); 

// create the bool filter for the condition above 
String[] names = {"stokes","roshan"}; 
BoolQueryBuilder aggFilter = QueryBuilders.boolQuery() 
    .must(QueryBuilders.termsQuery("Name", names)) 
    .must(QueryBuilders.rangeQuery("grade").lte(9.0)) 

// create the filter aggregation and add the year sub-aggregation 
FilterAggregationBuilder aggregation = AggregationBuilders.filter("agg") 
    .filter(aggFilter) 
    .subAggregation(yearAgg); 

// create the request and execute it 
SearchResponse response = client.prepareSearch(index) 
    .setTypes(datasquareID) 
    .addAggregation(aggregation) 
    .execute().actionGet(); 
System.out.println(response.toString()); 

В конце концов, это будет выглядеть следующим образом:

{ 
    "query": { 
    "match_all": {} 
    }, 
    "aggs": { 
    "agg": { 
     "filter": { 
     "bool": { 
      "must": [ 
      { 
       "terms": { 
       "Name": [ 
        "stokes", 
        "roshan" 
       ] 
       } 
      }, 
      { 
       "range": { 
       "grade": { 
        "lte": 9 
       } 
       } 
      } 
      ] 
     } 
     }, 
     "aggs": { 
     "by_year": { 
      "terms": { 
      "field": "year" 
      }, 
      "aggs": { 
      "sum_marks": { 
       "sum": { 
       "field": "marks" 
       } 
      }, 
      "sum_grade": { 
       "sum": { 
       "field": "grade" 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

Для документов выше, результат будет выглядеть следующим образом:

"aggregations": { 
     "agg": { 
     "doc_count": 2, 
     "by_year": { 
      "doc_count_error_upper_bound": 0, 
      "sum_other_doc_count": 0, 
      "buckets": [ 
       { 
        "key": 2015, 
        "doc_count": 2, 
        "sum_grade": { 
        "value": 18 
        }, 
        "sum_marks": { 
        "value": 176 
        } 
       } 
      ] 
     } 
     } 
    } 
+0

Спасибо за ответ Val. Теперь он работает отлично. Но если взглянуть на поля имен в документах, они начинаются с символа верхнего регистра, как «Name»: «Тейлор» «Название»: «Стокс» «Имя»: «Рошан» В перспективе запроса вы имели имена в нижнем регистре , – ravi

+0

Удивительный, рад, что это сработало !! – Val

+0

Спасибо за ответ Val. Теперь он работает отлично. Но если взглянуть на поля имен в документах, они начинаются с символа верхнего регистра, как «Name»: «Тейлор» «Название»: «Стокс» «Имя»: «Рошан» В перспективе запроса вы имели имена в нижнем регистре , String [] names = {"stokes", "roshan"} Но если я ищу имена, подобные String [] names = {"Stokes", "Roshan"} Не получив результат, как ожидалось. Получаю пустой совокупный результат. – ravi

Смежные вопросы