Skip to content

Avg aggregation over 0 documents/values yields Double.NaN if using transport client, but Double.POSITIVE_INFINITY if using REST client #43820

@ahubmann

Description

@ahubmann

Describe the feature: Running an avg aggregation when 0 documents/values match yields different values depending on connection type (TransportClient vs RestClient).

Elasticsearch version (bin/elasticsearch --version): 7.2.0 (and 6.x as well)

Plugins installed: []

JVM version (java -version): 11.0.3

OS version (uname -a if on a Unix-like system): Linux sascha 4.15.0-54-generic #58-Ubuntu SMP Mon Jun 24 10:55:24 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Description of the problem including expected versus actual behavior: Calculation of avg metric over 0 documents yields NaN if connected to Elasticsearch using transport client, but Double.POSITIVE_INFINITY if using REST client. IMHO the result of an operation should not depend on the connection type to the Elasticsearch cluster.

This seems to be related to the fact that internally, Elasticsearch takes two different routes to create the result of an avg aggregation:

Steps to reproduce: (see also attached elastic-avg.zip)

  1. Run Elasticsearch via Docker as run -it --rm -p 127.0.0.1:9200:9200 -p 127.0.0.1:9300:9300 -e "discovery.type=single-node" -e "cluster.name=elasticsearch" docker.elastic.co/elasticsearch/elasticsearch:7.2.0

  2. Index a sample document:

IndexRequest indexRequest = new IndexRequest("test").id("1").source(XContentFactory.jsonBuilder().startObject().field("value", 1).endObject());
client.index(indexRequest, RequestOptions.DEFAULT);
  1. Aggregate over a field with count 0:
protected static final AvgAggregationBuilder aggregation = AggregationBuilders.avg("test").field("value2");
  1. Run aggregation using TransportClient:
// execute aggregation over transport client
SearchResponse response = client.prepareSearch().addAggregation(aggregation).execute().actionGet();
Avg result = response.getAggregations().get("test");

// for transport client, the result is NaN
assertTrue(Double.isNaN(result.value()));
  1. Run aggregation using RestClient:
// execute aggregation over rest client
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchRequest.source(searchSourceBuilder);
searchSourceBuilder.aggregation(aggregation);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
Avg result = response.getAggregations().get("test");

// for rest client, the result is positive infinity
assertTrue(Double.isInfinite(result.value()));

Provide logs (if relevant):

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions