Ulong to double to ulong magic in Elasticsearch

Hi,

I'm currently testing edge cases for saving and retrieving c# base types in ES. Some things are not working as expected, e.g. saving decimal.MaxValue in an ES double field and then retrieving it back.

But one strange thing happens for ulong. There is no ulong numeric type in ES, so I map c# ulong to ES double.
Here is the mapping for the ULongMaxValueProperty as shown in Kibana:

"ULongMaxValueProperty": {
"type": "double"
}

ulong.MaxValue is 18446744073709551615. After saving my test document to ES, the stored value is shown in Kibana as

"ULongMaxValueProperty": 18446744073709552000.

The value is rounded up as expected, we have precision loss. And when trying to parse such a value with ulong.Parse("18446744073709552000") an overflow exception is thrown, as expected.

Then I run this query:

{
  "size": 10000,
  "sort": [],
  "query": {
    "term": {
      "ULongMaxValueProperty": {
        "value": 18446744073709551615
      }
    }
  },
  "aggs": {}
}

... and I get one document back, which is the one where ULongMaxValueProperty was set to ulong.MaxValue.
In the retrieved document we have:

"ULongMaxValueProperty": 18446744073709551615

How is it possible? How can the double field in ES store the ulong.MaxValue precisely up to the last digit?
In the same document there are other properties for min and max values and for long the min and max values are also precise up to the last digit, although in Kibana they are shown as rounded up.

For decimal, it does not work this way. Here the max und min values are truly rounded.

Although I get the precise ulong.MaxValue with the search request, I don't get it with an aggregation request. My aggregation request for the max value:

{
  "size": 0,
  "sort": [],
  "query": {
    "match_all": {}
  },
  "aggs": {
    "max": {
      "max": {
        "field": "ULongMaxValueProperty"
      }
    }
  }
}

And in the response we have:

"aggregations": {
    "max": {
      "Value": 1.8446744073709552E+19
    }
  }

Which is the rounded up double representation of ulong.MaxValue. It cannot be parsed back to ulong.
The aggregation response seems to contain only double? values as result, so here the cast to double happens and the precision is lost. I don't know if it is possible to tell ES, that it shall use the field type as the value type for the aggregation response.

So my question is: how is it possible that the term query returns the precise ulong max value (same for long min and max) from the double field of a document in ES? :thinking:

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.