Problem with float in range facet


(Jettro Coenradie) #1

Hi,
I have a float field that I want to use in a range facet. I give one range
to the facet like the following query.

{
"query": {
"matchAll": {}
},
"facets": {
"imageSize": {
"range": {
"field": "imageSize",
"ranges": [
{
"from": 1.9
}
]
}
}
}
}

If I have a document with the value 1.9 it is not included in the results.
If I change the from part to 1.89 however it is included. I am sure the
type of the field is 1.9, checked it in the mapping.

Any ideas what is the problem?

thanks,
Jettro

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/85e04977-4378-48cb-a6c1-e0c3b71fbad4%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


(Adrien Grand) #2

Hi,

This is a floating point rounding error. There are many numbers that
floating points cannot represent accurately and if you assign 1.9 to a
float, the value that will be stored is actually closer to 1.89999998.

Since the range query internally works on doubles, which have better
precision than floats, the 1.9 from the facet definition is not precisely
1.9 but very close thanks to double precision while your float in the index
is still close to 1.89999998 and thus compares less than the double
representation of 1.9.

There are two ways to work around this issue:

  • either store the imageSize field as a double so that the rounding error
    will be the same at indexing and faceting time,
  • or if your numbers have a finite number of digits, store them as
    integers instead. For example, if your image sizes only have two digits,
    you could store them all as (imageSize*10^2) which is an integer, and
    change your facet definition to be from: 190 instead of from: 1.9. This
    requires a bit more work on client side but a great benefit is that there
    won't be any more rounding issue.

On Wed, Jan 15, 2014 at 8:10 AM, Jettro Coenradie <
jettro.coenradie@gmail.com> wrote:

Hi,
I have a float field that I want to use in a range facet. I give one range
to the facet like the following query.

{
"query": {
"matchAll": {}
},
"facets": {
"imageSize": {
"range": {
"field": "imageSize",
"ranges": [
{
"from": 1.9
}
]
}
}
}
}

If I have a document with the value 1.9 it is not included in the results.
If I change the from part to 1.89 however it is included. I am sure the
type of the field is 1.9, checked it in the mapping.

Any ideas what is the problem?

thanks,
Jettro

--
You received this message because you are subscribed to the Google Groups
"elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/elasticsearch/85e04977-4378-48cb-a6c1-e0c3b71fbad4%40googlegroups.com
.
For more options, visit https://groups.google.com/groups/opt_out.

--
Adrien Grand

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/CAL6Z4j4A28BPaEZXnbQNyGgrT2UxfhnTsVL43cR1MpXK3sHsqA%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.


(Jettro Coenradie) #3

Thanks, that works.

Op woensdag 15 januari 2014 15:32:39 UTC+1 schreef Adrien Grand:

Hi,

This is a floating point rounding error. There are many numbers that
floating points cannot represent accurately and if you assign 1.9 to a
float, the value that will be stored is actually closer to 1.89999998.

Since the range query internally works on doubles, which have better
precision than floats, the 1.9 from the facet definition is not precisely
1.9 but very close thanks to double precision while your float in the index
is still close to 1.89999998 and thus compares less than the double
representation of 1.9.

There are two ways to work around this issue:

  • either store the imageSize field as a double so that the rounding error
    will be the same at indexing and faceting time,
  • or if your numbers have a finite number of digits, store them as
    integers instead. For example, if your image sizes only have two digits,
    you could store them all as (imageSize*10^2) which is an integer, and
    change your facet definition to be from: 190 instead of from: 1.9. This
    requires a bit more work on client side but a great benefit is that there
    won't be any more rounding issue.

On Wed, Jan 15, 2014 at 8:10 AM, Jettro Coenradie <jettro.c...@gmail.com<javascript:>

wrote:

Hi,
I have a float field that I want to use in a range facet. I give one
range to the facet like the following query.

{
"query": {
"matchAll": {}
},
"facets": {
"imageSize": {
"range": {
"field": "imageSize",
"ranges": [
{
"from": 1.9
}
]
}
}
}
}

If I have a document with the value 1.9 it is not included in the
results. If I change the from part to 1.89 however it is included. I am
sure the type of the field is 1.9, checked it in the mapping.

Any ideas what is the problem?

thanks,
Jettro

--
You received this message because you are subscribed to the Google Groups
"elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to elasticsearc...@googlegroups.com <javascript:>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/elasticsearch/85e04977-4378-48cb-a6c1-e0c3b71fbad4%40googlegroups.com
.
For more options, visit https://groups.google.com/groups/opt_out.

--
Adrien Grand

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/28c879e7-da53-4068-9a09-28b5f506a6f6%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


(system) #4