2015-12-04 79 views
1

我正在使用传输客户端从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" 
       } 
      } 
     ] 
    } 
} 

响应:

"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。它的工作现在很好。 但如果看名称字段中,他们与像 “名称”大写的启动文件:在项查询你在较低的情况下采取了名字“罗山” :“泰勒” “名称”:“斯托克斯” “名称” 。 – ravi

+0

真棒,很高兴它解决了! – Val

+0

感谢您的回答Val。它的工作现在很好。 但如果看名称字段中,他们与像 “名称”大写的启动文件:在项查询你在较低的情况下采取了名字“罗山” :“泰勒” “名称”:“斯托克斯” “名称” 。 String [] names = {“stokes”,“roshan”} 但是,如果我搜索名称,如 String [] names = {“Stokes”,“Roshan”} 没有按预期得到结果。我得到空的聚合结果。 – ravi