Как вложить агрегацию scriptedMetric в агрегацию терминов в java API elasticsearch?

Я хочу использовать агрегацию 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"
                    }
                }
            }
        }
    }
}

Но я не нашел, как это сделать в java API Elasticsearch.

Я пробовал так:

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];

Я много искал, но не могу найти демо.

Любая помощь будет оценена по достоинству.

Спасибо!


person lulijun    schedule 18.11.2017    source источник
comment
ты еще не решил?   -  person mlecz    schedule 09.04.2018
comment
@mlecz еще нет. Я сделал это в своем собственном приложении   -  person lulijun    schedule 09.04.2018
comment
Я только что решил это в своем случае (максимальная агрегация). А у вас похоже не хватает того же. Добавьте .field(имя поля) в построитель агрегации. Может быть, это поможет.   -  person mlecz    schedule 09.04.2018


Ответы (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;
}

'значение исходной конфигурации недействительно; должен иметь либо контекст поля, либо сценарий, либо помечен как развернутый». Я также столкнулся с этой ошибкой, пожалуйста, прочитайте комментарии в кодах, что является моим решением. Необходимо получить либо ParsedStringTerms, либо TermsAggregationBuilder.

person redfisky    schedule 25.09.2020