1

I have the following data:

[{
    "id": "1",
    "listItems": [
        {
            "key": "li1",
            "value": 100
        },
        {
            "key": "li2",
            "value": 5000
        }
    ]
},
{
    "id": "2",
    "listItems": [
        {
            "key": "li3",
            "value": 200
        },
        {
            "key": "li2",
            "value": 2000
        }
    ]
}]

I'm trying to do a NumericRangeQuery filter so that the MIN value in each document's listItems match up between a range. So for example, my range is 150 to 15000.

The only way I know how to write this is using a script query but it doesn't appear to work as the code still seems to grab any value under the listItems to attempt to match up against the range instead of grabbing the MIN like I told it to. Here's my query:

{
"track_total_hits": true,
"from": 0,
"min_score": 0.0,
"query": {
    "bool": {
        "must": [
            {
                "nested": {
                    "path": "listItems",
                    "query": {
                        "script": {
                            "script": "double minVal = 0; minVal = doc['listItems.value'][0]; for (wp in doc['listItems.value']) {if (wp < minVal) { minVal = wp;}} return minVal >= 150 && minVal <= 15000"
                        }
                    }
                }
            }
        ]
    }
}}

Anybody seeing something I don't?

2
  • did you get a chance to go through my answer, looking forward to get feedback from you :) Commented Sep 28, 2020 at 6:24
  • hey thank you for responding again, please see my question below. Commented Sep 28, 2020 at 13:06

1 Answer 1

1

The search query performs the following aggregation :

  1. Terms aggregation on the id field
  2. Min aggregation on listItems.value
  3. Bucket Selector aggregation that is a parent pipeline aggregation that executes a script that determines whether the current bucket will be retained in the parent multi-bucket aggregation.

Adding a working example with index mapping, index data, search query, and search result

Index Mapping:

{
  "mappings": {
    "properties": {
      "listItems": {
        "type": "nested" 
      },
      "id":{
        "type":"text",
        "fielddata":"true"
      }
    }
  }
}

Index Data:

{
    "id" : "1",
    "listItems" : 
        [
            {
                "key" : "li1",
                "value" : 100
            },
            {
                "key" : "li2",
                "value" : 5000
            }
        ]
}
{
    "id" : "2",
    "listItems" : 
        [
            {
                "key" : "li3",
                "value" : 200
            },
            {
                "key" : "li2",
                "value" : 2000
            }
        ]
}

Search Query:

{
    "size": 0,
    "aggs": {
        "id_terms": {
            "terms": {
                "field": "id"
            },
            "aggs": {
                "nested_entries": {
                    "nested": {
                        "path": "listItems"
                    },
                    "aggs": {
                        "min_position": {
                            "min": {
                                "field": "listItems.value"
                            }
                        }
                    }
                },
                "value_range": {
                    "bucket_selector": {
                        "buckets_path": {
                            "totalValues": "nested_entries>min_position"
                        },
                        "script": "params.totalValues >= 150 && params.totalValues < 15000"
                    }
                }
            }
        }
    }
}

Search Result:

"aggregations": {
    "id_terms": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "2",
          "doc_count": 1,
          "nested_entries": {
            "doc_count": 2,
            "min_position": {
              "value": 200.0
            }
          }
        }
      ]
    }
  }
Sign up to request clarification or add additional context in comments.

3 Comments

Hi thanks for responding again. So the only way to do this is through aggregation and not a typical document search query or filter? This does seem to work but it introduces a complexity to my existing code because my document is a lot larger than this with a lot more filtering than just simply trying to find the max min. We have separate logic for aggregation of the content and actually searching and return the document content for displaying (if that makes sense).
@user989953 Thanks for your reply :) I don't think this is possible using a typical search query or filter, as you want to find minimum value from each bucket (that has to be created using aggregation). And then on the buckets formed you want a range to be applied. So according to your use case and requirements, we can get the required result using aggregations only.
I did go ahead and marked your response as answer as I was able to apply it to my code with a couple minor tweaks to make it work the way I need it. Thank you again for the help.

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.