Skip to content

Source filtering & pretty-printing munges floating-point values #40202

Open
@DaveCTurner

Description

The JSON spec permits numbers of any length and precision, and we normally preserve the _source of documents verbatim so these numbers correctly round-trip through Elasticsearch. However, if source filtering or pretty-printing is enabled then Elasticsearch parses the JSON and manipulates it before returning it. This parsing process round-trips floating-point-like numbers (i.e. those that contain . or e) via IEEE754 doubles, which is a lossy conversion.

Railroad diagram for numbers in JSON

For example:

$ curl -XPUT 'http://localhost:9200/i' -H 'Content-type: application/json' --data-binary $'{"mappings":{"_doc":{"properties":{"f":{"type":"keyword"}}}}}'
{"acknowledged":true,"shards_acknowledged":true,"index":"i"}
$ curl 'http://localhost:9200/i/_doc?refresh' -H 'Content-type: application/json' --data-binary '{"f":123e0}'
{"_index":"i","_type":"_doc","_id":"rXe_lWkBKSHNNeEfa5L-","_version":1,"result":"created","forced_refresh":true,"_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}
$ curl 'http://localhost:9200/i/_doc?refresh' -H 'Content-type: application/json' --data-binary '{"f":1.2345678901234567890123456789}'
{"_index":"i","_type":"_doc","_id":"rne_lWkBKSHNNeEfbZJ-","_version":1,"result":"created","forced_refresh":true,"_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}
$ curl 'http://localhost:9200/i/_doc?refresh' -H 'Content-type: application/json' --data-binary '{"f":123e999999}'
{"_index":"i","_type":"_doc","_id":"r3e_lWkBKSHNNeEfbpJe","_version":1,"result":"created","forced_refresh":true,"_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}
$ curl -XGET 'http://localhost:9200/i/_search' # returns sources verbatim:
{"took":6,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"i","_type":"_doc","_id":"r3e_lWkBKSHNNeEfbpJe","_score":1.0,"_source":{"f":123e999999}},{"_index":"i","_type":"_doc","_id":"rXe_lWkBKSHNNeEfa5L-","_score":1.0,"_source":{"f":123e0}},{"_index":"i","_type":"_doc","_id":"rne_lWkBKSHNNeEfbZJ-","_score":1.0,"_source":{"f":1.2345678901234567890123456789}}]}}
$ curl -XGET 'http://localhost:9200/i/_search?pretty'
{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "i",
        "_type" : "_doc",
        "_id" : "r3e_lWkBKSHNNeEfbpJe",
        "_score" : 1.0,
        "_source" : {
          "f" : "Infinity" // should be 123e999999, not even a number any more
        }
      },
      {
        "_index" : "i",
        "_type" : "_doc",
        "_id" : "rXe_lWkBKSHNNeEfa5L-",
        "_score" : 1.0,
        "_source" : {
          "f" : 123.0 // should be 123e0
        }
      },
      {
        "_index" : "i",
        "_type" : "_doc",
        "_id" : "rne_lWkBKSHNNeEfbZJ-",
        "_score" : 1.0,
        "_source" : {
          "f" : 1.2345678901234567 // truncated, should be 1.2345678901234567890123456789
        }
      }
    ]
  }
}

$ curl -XGET 'http://localhost:9200/i/_search' -H 'Content-type: application/json' --data-binary $'{"_source":"f"}'
{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"i","_type":"_doc","_id":"r3e_lWkBKSHNNeEfbpJe","_score":1.0,"_source":{"f":"Infinity"}},{"_index":"i","_type":"_doc","_id":"rXe_lWkBKSHNNeEfa5L-","_score":1.0,"_source":{"f":123.0}},{"_index":"i","_type":"_doc","_id":"rne_lWkBKSHNNeEfbZJ-","_score":1.0,"_source":{"f":1.2345678901234567}}]}}

Relates #29622, #23796.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    :Search Foundations/SearchCatch all for Search Foundations>bugTeam:Search FoundationsMeta label for the Search Foundations team in Elasticsearchpriority:normalA label for assessing bug priority to be used by ES engineers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions