Filter on doubles rounded to integer bound values?

I have this query:

{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "text": "ik"
        }
      },
      "filter": {
        "bool": {
          "must": [
            {
              "range": {
                "lat2": {
                  "gte": 52.6018,
                  "lte": 52.6539
                }
              }
            },
            {
              "range": {
                "lng2": {
                  "gte": 6.9766,
                  "lte": 7.0622
                }
              }
            }
          ]
        } 
      }
    }
  }
}

Here is one of the results :

{
  "_index": "twitter20151105",
  "_type": "tweets",
  "_id": "662381428399841281",
  "_score": 1.9517577,
  "_source": {
    "text": "@Regenboogschaap ik!!! Ik!!",
    "lng2": 6.08333333,
    "lat2": 52.51666667
  }
}

This is clearly wrong. It looks like all values are trimmed to integer values for the test of the range. All results have 6 < lng2 < 7 and 52 < lat2 < 53.
How do I fix this?

What are those fields mapped as?

I didn't use an explicit mapping.

Here is a full example, entering and querying starting with a new database.

Example 1:

curl -XPUT "http://localhost:9200/numtest1/data/2" -d'{"val": 1.5}'
curl -XPUT "http://localhost:9200/numtest1/data/3" -d'{"val": 2.2}'
curl -XPUT "http://localhost:9200/numtest1/data/4" -d'{"val": 2.6}'
curl -XPUT "http://localhost:9200/numtest1/data/5" -d'{"val": 3.5}'
curl -XPOST "http://localhost:9200/numtest1/data/_search?pretty" -d'
{
  "query": {
    "filtered": {
      "query": {
        "match_all": { }
      },
      "filter": {
        "range": {
          "val": {
            "gte": 2.5,
            "lte": 2.7
          }
        }
      }
    }
  }
}'

This gives what I would expect, only 2.6

Example 2:

curl -XPUT "http://localhost:9200/numtest2/data/1" -d'{"val": 0}'
curl -XPOST "http://localhost:9200/numtest2/data/_search?pretty" -d'{"query":{"match_all":{}}}'
curl -XPUT "http://localhost:9200/numtest2/data/2" -d'{"val": 1.5}'
curl -XPUT "http://localhost:9200/numtest2/data/3" -d'{"val": 2.2}'
curl -XPUT "http://localhost:9200/numtest2/data/4" -d'{"val": 2.6}'
curl -XPUT "http://localhost:9200/numtest2/data/5" -d'{"val": 3.5}'
curl -XPOST "http://localhost:9200/numtest2/data/_search?pretty" -d'
{
  "query": {
    "filtered": {
      "query": {
        "match_all": { }
      },
      "filter": {
        "range": {
          "val": {
            "gte": 2.5,
            "lte": 2.7
          }
        }
      }
    }
  }
}'

This gives as a result the values 2.2 and 2.6

Entering value 0 first, and querying before doing further inserts changes the outcome.

This is Elasticsearch 2.0.0

1 Like

So you are using the dynamic field mapping. Depending on the values ES sees in the documents you index it will infer their types. For more on the exact rules see here: Dynamic field mapping | Elasticsearch Guide [2.0] | Elastic

When unsure which types your fields are mapped to you can retrieve the mapping for your index:

Hope this helps,
Isabel

1 Like