可以在 java 中使用 bucket_script 吗?

is it possible to use bucket_script in java?

我看了Aggregations官方文档,上面说

Elasticsearch provides a full Java API to play with aggregations. See the Aggregations guide.

但遗憾的是,我无法将以下查询翻译成 Java 代码。

{
  “size”: 0,
  “aggs”: {
    “mallBucket”: {
      “terms”: {
        “field”: “mallId”,
        “size”: 20,
        “min_doc_count”: 3,
        “shard_size”: 10000
      },
      “aggs”: {
        “totalOrderCount”: {
          “value_count”: {
            “field”: “orderSn”
          }
        },
        “filteredCoupon”: {
          “filter”: {
            “terms”: {
              “tags”: [
                “hello”,
                “cool”
              ]
            }
          },
          “aggs”: {
            “couponCount”: {
              “value_count”: {
                “field”: “orderSn”
              }
            }
          }
        },
        “countRatio”: {
          “bucket_script”: {
            “buckets_path”: {
              “orderCount”: “totalOrderCount”,
              “couponCount”: “filteredCoupon>couponCount”
            },
            “script”: “params.couponCount/params.orderCount”
          }
        },
        “ratio_bucket_sort”: {
          “bucket_sort”: {
            “sort”: [
              {
                “countRatio”: {
                  “order”: “desc”
                }
              }
            ],
            “size”: 20
          }
        }
      }
    }
  }
}

official Java Client documentation开始,你可以使用PipelineAggregatorBuilders.bucketScript()的方法来实现你所需要的。

感谢@Val的帮助,我解决了这个烦人的问题如下(仅供参考)。

        Map<String, String> pathMap = new HashMap<>();
        pathMap.put("orderCount", ES_AGGS_COUNT_ONE);
        pathMap.put("couponCount", String.format("%s>%s", ES_AGGS_FILTER_ONE, ES_AGGS_COUNT_TWO));
        AggregationBuilder aggregationBuilder = AggregationBuilders.terms(ES_BUCKETING).field(ES_FIELD_MALL_ID)
                .minDocCount(abnormalCouponHiveConsumingTask.getMinOrderCount()).shardSize(10_000).size(getTopCount(request))
                .subAggregation(AggregationBuilders.count(ES_AGGS_COUNT_ONE).field(ES_FIELD_ORDER_SN)).subAggregation(
                        AggregationBuilders.filter(ES_AGGS_FILTER_ONE, getTagFilter(request))
                                .subAggregation(AggregationBuilders.count(ES_AGGS_COUNT_TWO).field(ES_FIELD_ORDER_SN))
                                .subAggregation(AggregationBuilders.sum(ES_SUM_ONE).field(ES_FIELD_COUPON_AMOUNT)))
                .subAggregation(PipelineAggregatorBuilders
                        .bucketScript(ES_AGGS_SCRIPT, pathMap, new Script("params.couponCount/params.orderCount")))
                .subAggregation(PipelineAggregatorBuilders.bucketSort(ES_SORT,
                            Lists.newArrayList(new FieldSortBuilder(ES_AGGS_SCRIPT).order(SortOrder.DESC))).from(0)
                            .size(getTopCount(request)));

一路上又遇到了ES客户端版本导致的问题,升级到7.4org.elasticsearch.common.ParsingException解决了。