Filter on doubles rounded to integer bound values?


(Peter Kleiweg) #1

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?


(Mark Walkom) #2

What are those fields mapped as?


(Peter Kleiweg) #3

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


(Isabel Drost-Fromm) #4

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: https://www.elastic.co/guide/en/elasticsearch/reference/2.0/dynamic-field-mapping.html

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

https://www.elastic.co/guide/en/elasticsearch/reference/2.0/indices-get-mapping.html

Hope this helps,
Isabel


(system) #5