Elasticsearch 5 - Weird error (value source config is invalid; must have either a field context or a script or marked as unwrapped)

Viewed 3071

I'm busy upgrade our Java platform from ES 2 to ES 5.4.3, So far everything is going ok, Except one query returns an error that doesn't make must sense. Has anyone seen this before?

Caused by: java.lang.IllegalStateException: value source config is invalid; must have either a field context or a script or marked as unwrapped
at org.elasticsearch.search.aggregations.support.ValuesSourceConfig.toValuesSource(ValuesSourceConfig.java:228)
at org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory.createInternal(ValuesSourceAggregatorFactory.java:51)
at org.elasticsearch.search.aggregations.AggregatorFactory.create(AggregatorFactory.java:221)
at org.elasticsearch.search.aggregations.AggregatorFactories.createSubAggregators(AggregatorFactories.java:208)
at org.elasticsearch.search.aggregations.AggregatorBase.<init>(AggregatorBase.java:78)
at org.elasticsearch.search.aggregations.bucket.BucketsAggregator.<init>(BucketsAggregator.java:48)
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregator.<init>(TermsAggregator.java:178)
at org.elasticsearch.search.aggregations.bucket.terms.AbstractStringTermsAggregator.<init>(AbstractStringTermsAggregator.java:42)
at org.elasticsearch.search.aggregations.bucket.terms.GlobalOrdinalsStringTermsAggregator.<init>(GlobalOrdinalsStringTermsAggregator.java:92)
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregatorFactory$ExecutionMode$2.create(TermsAggregatorFactory.java:277)
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregatorFactory.doCreateInternal(TermsAggregatorFactory.java:176)
at org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory.createInternal(ValuesSourceAggregatorFactory.java:55)
at org.elasticsearch.search.aggregations.AggregatorFactory.create(AggregatorFactory.java:221)
at org.elasticsearch.search.aggregations.AggregatorFactories.createTopLevelAggregators(AggregatorFactories.java:224)
at org.elasticsearch.search.aggregations.AggregationPhase.preProcess(AggregationPhase.java:55)
at org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:106)
at org.elasticsearch.search.SearchService.loadOrExecuteQueryPhase(SearchService.java:247)
at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:262)
at org.elasticsearch.action.search.SearchTransportService$6.messageReceived(SearchTransportService.java:339)
at org.elasticsearch.action.search.SearchTransportService$6.messageReceived(SearchTransportService.java:336)
at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:69)
at org.elasticsearch.transport.TransportService$7.doRun(TransportService.java:627)
at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:638)
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
... 1 more
2 Answers

I'm not sure without further context, but I'll note here that I resolved this error by adding a "field" property to my AggregationBuilders which I was missing before.

Before:

RangeAggregationBuilder range = AggregationBuilders.range("range_name");

After:

RangeAggregationBuilder range = AggregationBuilders.range("range_name").field("whatever.mapping.you.need");

Again, without further context it's really hard to say in your specific case. But considering this is Java (as was my issue) and not kibana-related and since mine was such an easy fix, I hope that someone (probably, future-me) that comes across this will see this and be saved much frustration.

    @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;
}

'value source config is invalid; must have either a field context or a script or marked as unwrapped' i encountered this error as well using spring-data-elasticsearch, please read the comments in the codes, which is my solution. Either ParsedStringTerms or TermsAggregationBuilder need to be retrieved.

Related