【问题标题】:How to nested a scriptedMetric aggregation into a term aggregation in elasticsearch's java api?如何将scriptedMetric聚合嵌套到elasticsearch的java api中的术语聚合中?
【发布时间】:2020-09-25 11:04:02
【问题描述】:

我想使用 Elasticsearch 的聚合来做 OLAP 数据分析。 我要做的是将scriptedMetric聚合嵌套到术语聚合中,如下所示(正确)

{
    "from": 0,
    "size": 0,
  "query":{
    "bool":{
      "must":[
        {
          "match":{
            "poi_id":1
          }
        }
        ]
    }
  },
    "aggregations": {
        "poi_id": {
            "terms": {
                "script": {
                    "inline": "doc['poi_id'].value + 1"
                }
            },
            "aggregations": {
                "price": {
                    "sum": {
                        "field": "price"
                    }
                }
            }
        }
    }
}

但我没有在 Elasticsearch 的 java api 中找到如何做到这一点。

我试过这样:

SearchResponse response = client.prepareSearch("poi")
        .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
        .setFetchSource(new String[]{"poi_id","poi_name"}, null)
        .setQuery(QueryBuilders.termQuery("poi_id", 1))
        .addAggregation(AggregationBuilders.terms("poi_id").subAggregation((AggregationBuilders.scriptedMetric("poi_id").mapScript(new Script("doc['poi_id'].value + 1")))))
        .execute()
        .actionGet();

但出现错误

Caused by: NotSerializableExceptionWrapper[: value source config is invalid; must have either a field context or a script or marked as unwrapped]; nested: IllegalStateException[value source config is invalid; must have either a field context or a script or marked as unwrapped];

我搜索了很多,但找不到演示。

任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • 你解决了吗?
  • @mlecz 还没有。我在自己的应用程序中做到了
  • 我刚刚在我的情况下解决了它(最大聚合)。而你似乎缺乏同样的东西。将 .field("fieldname) 添加到您的聚合构建器中。也许会有所帮助。

标签: elasticsearch elasticsearch-aggregation


【解决方案1】:
    @Override
public Map<String, Object> sumPriceAggregation(String field, int page, int size) {
    if (StringUtils.isEmpty(field)) {
        field = "brandName";
    }
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    PageRequest pageRequest = PageRequest.of(page, size);
    queryBuilder.withPageable(pageRequest);
    queryBuilder.withSourceFilter(new FetchSourceFilter(new String[] {""}, null));
    String termStr = field.toUpperCase();
    TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(termStr)
            .field(field)
            .subAggregation(AggregationBuilders.sum("totalPrice").field("price")); //be aware this is subAggregation
    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
    nativeSearchQueryBuilder.addAggregation(termsAggregationBuilder);
    AggregatedPage<GamingLaptop> aggregatedPage = elasticsearchRestTemplate.queryForPage(
            nativeSearchQueryBuilder.build(), GamingLaptop.class);
    Aggregations aggregations = aggregatedPage.getAggregations();
    ParsedStringTerms stringTerms = aggregations.get(termStr);
    List<? extends Terms.Bucket> buckets = stringTerms.getBuckets();
    HashMap<String, Object> map = new HashMap<>();
    buckets.parallelStream().forEach(bucket -> {
        String key = bucket.getKeyAsString();
        long docCount = bucket.getDocCount();
        map.put(key, docCount);
        ParsedSum sum = (ParsedSum) bucket.getAggregations().asMap().get("totalPrice"); //make sure you get the aggregation here
        map.putIfAbsent("sum", sum.getValue());
    });
    return map;
}

'值源配置无效;必须有字段上下文或脚本或标记为未包装' 我也遇到了这个错误,请阅读代码中的 cmets,这是我的解决方案。 ParsedStringTermsTermsAggregationBuilder 需要检索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多