Filter over dynamic nested fields with aggregation

I have products with dynamic attributes (filters). I need to get dynamically counts for each value for the filter according to the search query.

I have following mapping for products index:

{  
   "products":{  
      "mappings":{  
         "properties":{  
            ...
            "dynamicFilters":{  
               "type":"nested",
               "properties":{  
                  "name":{  
                     "type":"keyword"
                  },
                  "value":{  
                     "type":"keyword"
                  }
               }
            },
            ...
         }
      }
   }
}

And following aggregation request:

'size': 0,
'query': {
    'bool': {
        'must': {
            'match': {
                'category': 'Notebooks'
            }
        },
        'filter': {
            {'nested': {
                'path': 'dynamicFilters',
                'query': {
                    'bool': {
                        'filter': {
                            {'term': {'dynamicFilters.name': 'processor'}},
                            {'terms': {'dynamicFilters.value': {'Ryzen 7'}}},
                        },
                    }
                }
            },
        }
    }
},

'aggs': {
    //'dynamicFilters': {
        //'global': {},   <-- global type commented here
        //'aggs': {
            'dynamicFilters': {
                'nested': {
                    'path': 'dynamicFilters',
                },
                'aggs': {
                    'name': {
                        'terms': {
                            'field': dynamicFilters.name',
                            'size': 20
                        },
                        'aggs': {
                            'value': {
                                'terms': {
                                    'field': 'dynamicFilters.value',
                                    'size': 20
                                }
                            }
                        }
                    },
                }
            },
        //}
    //}
},

The problem is when in the search query will be enabled filter, for instance, "proccesor" with value "Ryzen 7" - in response won't be aggregation for all "processor" values, except "Ryzen 7".

I've tried to make this work with global type , but in this case aggs stops working with search query and return all existing counts for values.

Any help will be highly appreciated, thank you!

you may want to check the post_filter functionality, that might or might not help, depending on the concrete use-case (I did something within an ecommerce use-case, started with post_filter, but ended up with very custom aggs).

Thank you for your response! But post_filter does the same as query filter from my example.

The key point of my problem is dynamic fields.

post_filter does not the same as your current query. If you put the filter part of your query into the post filter, your aggregation response will contain the all the data only filtered by the category.

If you intended something different, maybe redescribe it with different words, so I can understand.

Ok. Let's imagine I have some products and some dynamic filters for them: Display diagonal, HDD size, Proccessor.
I enable filter Processor with value "Ryzen 7". Now I need to get from ES response counts of products for all variants of dynamic filters, that match enabled filter ("Ryzen 7"). Like so:

Display diagonal (150 products)

  • 12" (5 products)
  • 14" (10 products)
  • 15.6" (25 products)

HDD size (150 products)

  • 512Mb (2 products)
  • 1TB (10 products)
  • 6TB (7 products)

Processor (150 products)

  • + Ryzen 7 (10 products)
  • Core i5 (90 products)
  • Core i7 (50 products)

For first two filters I get correct results. But for Processor I have count only for value "Ryzen 7" (because it is enabled in the filter).

2 Likes

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.