# How to sort on nested values that matches certain filters

**URL:** <https://discuss.elastic.co/t/how-to-sort-on-nested-values-that-matches-certain-filters/362557>\
**Category:** Elasticsearch\
**Tags:** painless\
**Created:** [July 4, 2024, 1:25pm UTC](https://discuss.elastic.co/t/how-to-sort-on-nested-values-that-matches-certain-filters/362557 "2024-07-04T13:25:43Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![juanm889](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/juanm889/32/135806_2.png) [@juanm889](https://discuss.elastic.co/u/juanm889)\
**Post date:** [July 4, 2024, 1:25pm UTC](https://discuss.elastic.co/t/how-to-sort-on-nested-values-that-matches-certain-filters/362557/1 "2024-07-04T13:25:43Z")

</div>

I want to sort by the field has\_stock (sending false to the bottom) but only on those elements of the nested that matches the query

```auto
{
    "mappings": {
        "properties": {
            "product_id": {
                "type": "integer"
            },
            "name": {
                "type": "text"
            },
            "variants": {
                "dynamic": "strict",
                "type": "nested",
                "properties": {
                  "variantId": {
                    "type": "integer"
                  },
                  "variations": {
                    "type": "nested",
                    "dynamic": "strict",
                    "properties": {
                      "option_name": {
                        "type": "keyword"
                      },
                      "option_value": {
                        "type": "keyword"
                      }
                    }
                  },
                  "stock": {
                    "type": "integer"
                  },
                  "has_stock": {
                    "type": "boolean",
                    
                  }
            }
          }
        }
    }
}

```

lets say I have a query like this that filters colors red or yellow and size M

```auto
{
  "query": {
    "nested": {
      "path": "variants",
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "variants.variations",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "variants.variations.option_name": "colour"
                        }
                      },
                      {
                        "terms": {
                          "variants.variations.option_value": ["red", "yellow"]
                        }
                      }
                    ]
                  }
                }
              }
            },
               {
              "nested": {
                "path": "variants.variations",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "variants.variations.option_name": "size"
                        }
                      },
                      {
                        "term": {
                          "variants.variations.option_value": "L"
                        }
                      }
                    ]
                  }
                }
              }
            
          ]
        }
      }
    }
  }
}

```

so far I was able to do something like this with scripting

```auto

 "sort": [
    {
      "_script": {
        "type": "number",
        "script": {
          "source": """
            int hasStock = 0;
            for (def variant : params['_source'].variants) {
              for (def variation : variant.variations) {
               
                if (
(variation.option_name == 'color' && (variation.option_value == 'red' || variation.option_value == 'yellow')) || 
(variation.option_name == 'size' && (variation.option_value == 'M') || 

) {
                  hasStock = variant.has_stock ? 1 : 0;
                  break;
                }
              }
              if (hasStock == 1) {
                break;
              }
            }
            return hasStock;
          """,
          "lang": "painless"
        },
        "order": "desc"
      }
    }
    ]

```

but this alternative iterates over all variants, not just the one that matches the filter. I wonder if there's a more performant way to run this query
