使用JavaAPI在ElasticSearch多字段组中提取总和聚合的问题

时间:2018-01-31 06:36:21

标签: java elasticsearch

使用ElasticSearch 5.2和group by正在进行similer

select city,institutionId, SUM(appOpenCount) from XYZ where ( time > 123 && appOpenCount > 0 ) group by city, institutionId.

当我使用curl方法时,我有它工作,但是当它被转换为java api时,我错过了一些导致我无法得到总和聚合的最后部分的东西。

我有一个类型 temp_type ,下面给出了映射。

{
"temp_index" : {
"mappings" : {
  "temp_type" : {
    "properties" : {
      "appOpenCount" : {
        "type" : "integer"
      },
      "city" : {
        "type" : "keyword"
      }
      "institutionId" : {
        "type" : "keyword"
      },
      "time" : {
        "type" : "long"
      }
    }
  }
}
}
}

我的聚合XGET调用看起来像这样。

curl -XGET "http://localhost:9200/temp_index/temp_type/_search?pretty" -d'
{
"size":0,
"_source":false,
"from" : 0,
"query": {
     "bool": {
        "must": [
         {"range": { "time": { "gte": 1513744603000 } } },
         { "range": { "appOpenCount": { "gt": 0 } } }
         ]
      }
},
"aggregations": {
    "city-aggs": {
        "terms": { "field": "city"},
        "aggregations": {
             "intitution-agg": {
                 "terms": { "field": "institutionId" },
                 "aggregations": {
                        "appOpenCount": { "sum": { "field": "appOpenCount" }}}
              }
            }
       }
    }
}'

响应是完美的(聚合数字在数学上是有意义的)

{
 "took" : 57,
 "timed_out" : false,
 "_shards" : { ... },
 "hits" : {...  },
 "aggregations" : {
   "city-aggs" : {
     "doc_count_error_upper_bound" : 0,
     "sum_other_doc_count" : 0,
     "buckets" : [
       {
        "key" : "city-1",
        "doc_count" : 25,
        "intitution-agg" : {
          "doc_count_error_upper_bound" : 0,
          "sum_other_doc_count" : 0,
          "buckets" : [
            {
             "key" : "inst-1",
             "doc_count" : 5,
             "appOpenCount" : {
              "value" : 15.0
             }
            }
          ]
        }
      }
    ]
  }
}

使用它作为模板我将其转换为Java API调用,我能够执行它并访问city-agg键和INSTIT-agg键,但我不知道如何访问appOpenCount agg。基本上为Sum聚合获取null。

// bool query
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> mustQueries = boolQueryBuilder.must();
mustQueries.add(QueryBuilders.rangeQuery("time").gte(startTime));
mustQueries.add(QueryBuilders.rangeQuery("appOpenCount").gt(0));
queryBuilder = boolQueryBuilder;

// aggregationbuilder
AggregationBuilder aggregationBuilder = null;
TermsAggregationBuilder cityAggs = AggregationBuilders.terms("city-aggs").field("city");
TermsAggregationBuilder institutionAggs = AggregationBuilders.terms(
                "institution-agg").field("institutionId");
SumAggregationBuilder fieldAggBuilder = AggregationBuilders.sum("appOpenCount").field("appOpenCount");
aggregationBuilder = cityAggs.subAggregation(institutionAggs).subAggregation(fieldAggBuilder);

// search call
SearchResponse searchResponse = client.prepareSearch(indexName)
                .setTypes(typeName)
                .setQuery(queryBuilder)
                .addAggregation(aggregationBuilder)
                .setFrom(0)
                .setSize(0)
                .execute().actionGet();

// Iterate the searchResponse
Terms cityAggsTerms = searchResponse.getAggregations().get("city-aggs");
List<Terms.Bucket> mainCityBuckets = cityAggsTerms.getBuckets();
for (Terms.Bucket mainCityBucket : mainCityBuckets) {
    String cityName = mainCityBucket.getKeyAsString();
    LOGGER.info("CityName : " + cityName); // all good
    Terms institutionTerms = mainCityBucket.getAggregations().get("institution-agg");
    List<Terms.Bucket> institutionBuckets = institutionTerms.getBuckets();
    for (Terms.Bucket institutionBucket : institutionBuckets) {
        String institutionName = institutionBucket.getKeyAsString();
        LOGGER.info("InstitutionName : " + institutionName ); // all good
        Sum appOpenCountSum = institutionBucket.getAggregations().get("appOpenCount");
        if(appOpenCountSum != null) {
          double appOpenCount = appOpenCountSum.getValue();
          LOGGER.info("InstitutionName : " + institutionName +
                                " and appOpenCount is " + appOpenCount);
        } else {
          LOGGER.info("appOpenCountSum is null");
        }
     } // institution for
  }// city for

如何访问appOpenCount聚合的值。我正在打击我的&#34; appOpenCountSum&#34;变量为null。任何帮助,将不胜感激。我能够访问 city-agg institution-agg 并获得正确的值。不确定如何访问Term.Bucket

中的appOpenCount聚合

我按照弹性搜索文档中提供的示例进行了此操作

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/_metrics_aggregations.html#java-aggs-metrics-sum

已经深入细分,希望它也能帮助其他人。

编辑:问题是我在java中构建聚合查询的方式。 fieldAggBuilder应该添加到institutionAggs而不是我以前的方式。以下更正的代码。

// aggregationbuilder
AggregationBuilder aggregationBuilder = null;
TermsAggregationBuilder cityAggs = AggregationBuilders.terms("cityaggs").field("city");
TermsAggregationBuilder institutionAggs = AggregationBuilders.terms(
            "institution-agg").field("institutionId");
SumAggregationBuilder fieldAggBuilder = 
AggregationBuilders.sum("appOpenCount").field("appOpenCount");
institutionAggs.subAggregation(fieldAggBuilder); // this was missing previously
aggregationBuilder = cityAggs.subAggregation(institutionAggs);

0 个答案:

没有答案