elasticsearch - 聚合和过滤器的问题

时间:2015-12-04 18:26:45

标签: java 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的名称“Stokes”或“Roshan”来计算商标总数和等级总和,并将它们按“年”分组。请告诉我我的方法是否正确。请告诉我你的建议。

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" : []
                }
            }
        ]
    }
}

请让我知道我的要求的解决方案。

1 个答案:

答案 0 :(得分:2)

我认为问题出在您的filters汇总中。总而言之,您希望将聚合过滤到文档“... with names”Stokes“或”Roshan“,其等级小于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
                  }
               }
            ]
         }
      }
   }