1

I have a prop containing an array of integers:

_source: {
  counts: [
    11,
    7,
    18,
    3,
    22
  ]
}

From another post I know that I can filter by a range using:

{
  "query": {
    "bool": {
      "must": {
        "match_all": {}   
      },  
      "filter": {
        "range": {
          "counts": {
            "gte": 10,
            "lte": 20
          }
        }
      }
    }
  }
}

However, I need to additionally know if the range match count is greater than a certain number. For instance, I only want records back which have less than 3 counts matching between 10 and 20.

3
  • yeah, also you may want to add a order to those matched 3 counts. like say i want records back in ascending order Commented Sep 20, 2016 at 15:23
  • This might help stackoverflow.com/a/15548868/689625 Commented Sep 20, 2016 at 15:58
  • @jay that seems to allow me to filter by length, but this is a conditional situation where only length of a certain condition is filtered. Commented Sep 20, 2016 at 16:02

1 Answer 1

1

Mapping used:

{
  "properties" : {
    "counts" : {
      "type" :    "integer"
    }
  }
}

These are the docs I indexed:

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
      {
        "_index": "test_index",
        "_type": "test",
        "_id": "2",
        "_score": 1,
        "_source": {
          "counts": [
            13,
            17
          ]
        }
      },
      {
        "_index": "test_index",
        "_type": "test",
        "_id": "1",
        "_score": 1,
        "_source": {
          "counts": [
            11,
            7,
            18,
            3,
            22
          ]
        }
      },
      {
        "_index": "test_index",
        "_type": "test",
        "_id": "3",
        "_score": 1,
        "_source": {
          "counts": [
            11,
            19
          ]
        }
      }
    ]
  }
}

Now try this query:

    {
          "query": {
            "bool": {
              "must": {
                "match_all": {}   
              },  
              "filter": [
                        {"script" : { "script" : "doc['counts'].values.size() < 4" }},
                         {"range": { "counts": { "gte": 10, "lte": 20 } }}
                        ]
                }
          }
 }

Results: Only doc id 2 and 3 are returned. Doc 1 is not returned.

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1,
    "hits": [
      {
        "_index": "test_index",
        "_type": "test",
        "_id": "2",
        "_score": 1,
        "_source": {
          "counts": [
            13,
            17
          ]
        }
      },
      {
        "_index": "test_index",
        "_type": "test",
        "_id": "3",
        "_score": 1,
        "_source": {
          "counts": [
            11,
            19
          ]
        }
      }
    ]
  }
}

Is this what you are trying to do?

Sign up to request clarification or add additional context in comments.

1 Comment

That looks like exactly what I'm trying to accomplish! Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.