mooor
mooor

Reputation: 347

is there a way to query range when maximal range is defined by an array with two numbers

I need to write an elastic range query that operates on a following index format

    ...
    "facetProperties": {
      "fid641616": [
        31.75,
        44.45
      ]
    }
    ...

the following query works only if lt or gt matches the lower or the upper bound of the max range. As soon as I try to narrow both ends, there are no results.

    {
      "query": {
        "bool": {
          "should": [{
            "range": {
              "facetProperties.fid641616": {
                "gt": 33,
                "lt": 42
              }
            }
          }]
        }
      },
      "from": 0,
      "size": 250,
      "sort": [

      ],
      "aggs": {

      },
      "_source": "facetProperties.fid641616"
    }

Is there a way to get this working without modifying the index?

update1 - some use cases: query range:

    "range": {
              "facetProperties.fid641616": {
                "gt": 33,
                "lt": 42
             }
          }

    facet1 : [31] - should not be found
    facet2 : [31,45] - should be found 
    facet1 : [31,32] - should not be found
    facet1 : [44,45] - should not be found

Upvotes: 0

Views: 44

Answers (1)

Kamal Kunjapur
Kamal Kunjapur

Reputation: 8860

Basically it is not possible to query based on the range or difference of two numbers in an array using conventional DSL queries in ES but you can do that using script.

Below is the document and sample script that should help you.

Sample Document:

POST range_index/_doc/1
{
  "array": [31.75, 44.45]
}

Query:

POST range_index/_search
{
  "query": {
    "script": {
      "script": {
        "source": """
          List list = doc['array'];
          if(list.size()==2){
            long first_number = list.get(0);
            long last_number = list.get(1);

            if(params.gt < first_number)
              return false;

            if(params.lt > last_number)
              return false;

            if((last_number - first_number) >= (params.lt - params.gt))
              return true;
          }
          return false;
        """,
        "params": {
          "gt": 33,
          "lt": 42
        }
      }
    }
  }
}

What I've done is simply created a script that would return you documents having the difference of gt and lt that you have mentioned in your query.

You should be able to view the document I've mentioned in the result. Note that I'm assuming that the field array would be in asc order.

Basically it would return all the documents having difference of 42-33 i.e. 9.

Let me know if that helps!

Upvotes: 2

Related Questions