Search code examples
elasticsearchelasticsearch-dslelasticsearch-query

Storing and searching units and value ranges in Elasticsearch


I want to store multiple numerical ranges (array of integer_range) for a document. Each set of ranges is associated to a unit (a text field).

Here's an example:

PUT nested_index/_doc/1
{
  "operating_temperature": [
    {
      "unit": "kelvin",
      "value": [
        {
          "gte": 300,
          "lte": 500
        }
      ]
    },
    {
      "unit": "celcius",
      "value": [
        {
          "gte": 0,
          "lte": 30
        },
        {
          "gte": 70,
          "lte": 200
        }
      ]
    }
  ]
}

PUT nested_index/_doc/2
{
  "operating_temperature": [
    {
      "unit": "celcius",
      "value": [
        {
          "gte": 30,
          "lte": 400
        }
      ]
    }
  ]
}

Now I want to query for a document with an operating_temperature range of 400 to 450 Kelvins. I should get back only document 1 from this query.

I constructed my query like so:

GET nested_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "operating_temperature",
            "query": {
              "term": {
                "operating_temperature.unit": {
                  "value": "kelvin"
                }
              }
            }
          }
        },
        {
          "nested": {
            "path": "operating_temperature",
            "query": {
              "range": {
                "operating_temperature.value": {
                  "gte": 400,
                  "lte": 450
                }
              }
            }
          }
        }
      ]
    }
  }
}

This does not return any matches. I don't understand why it is not working.


Solution

  • The field operating_temperature.value should be array? If it is not an array, I recommend avoiding using an array to facilitate the query. The problem is that you have not determined (value.gte and value.lte) the field in the range query.

    GET nested_index/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "inner_hits": {},
                "path": "operating_temperature",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "operating_temperature.unit": {
                            "value": "kelvin"
                          }
                        }
                      },
                      {
                        "range": {
                          "operating_temperature.value.gte": {
                            "lte": 400
                          }
                        }
                      },
                      {
                        "range": {
                          "operating_temperature.value.lte": {
                            "gte": 450
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }