Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElasticSearch - how to exclude filter from aggregations?

I have filtered query with 3 filters: "query": "iphone", color:5, category:10, brand:25.

How can I get amount of products in each brand which have color:5 and category:10?

In Solr I did it like:

fq={!tag=tag_facet_brand}facet_brand:"564"&facet.field={!ex=tag_facet_brand}facet_brand

How can I exclude 1 filter from aggregation context? (I can't use global, because I loose query:iphone, I can't use post_filter - because of performance).

like image 564
Alex Sharov Avatar asked Oct 09 '14 03:10

Alex Sharov


2 Answers

We are just moving from SOLR and we are facing the same issue.

You could try global bucket then add a query filter for each bucket :

"filter" : {
            "query" : {
                "query_string" : {
                    "query" : "iPhone"
                }
            }
        }

You should end with something like :

{
    "size": 10,
    "query": {
        "query_string": {
            "query": "iphone"
        }
    },
    "filter": {
        "bool": {
            "must": [
                {
                    "term": {
                        "brand": "564"
                    }
                },
                {
                    "term": {
                        "color": "5"
                    }
                },
                {
                    "term": {
                        "category": "10"
                    }
                }
            ]
        }
    },
    "aggs": {
        "all": {
            "global": {},
            "aggs": {
                "keyword": {
                    "filter": {
                        "bool": {
                            "must": [
                                {
                                    "query": {
                                        "query_string": {
                                            "query": "iphone"
                                        }
                                    }
                                },
                                {
                                    "term": {
                                        "color": "5"
                                    }
                                },
                                {
                                    "term": {
                                        "category": "10"
                                    }
                                }
                            ]
                        }
                    },
                    "aggs": {
                        "brand": {
                            "terms": {
                                "field": "brand"
                            }
                        }
                    }
                }
            }
        }
    }
}
like image 123
Lionel Sengkouvanh Avatar answered Oct 03 '22 03:10

Lionel Sengkouvanh


In addition to @Lionel Sengkouvanh answer, here's the equivalent with the java API:

SearchRequestBuilder request = client
  .prepareSearch(INDEX_NAME)
  .setQuery(theQuery)
  ...
  .addAggregation(
     AggregationBuilders.global("all").subAggregation(      
       AggregationBuilders.filter("keyword").filter(filter).subAggregation(
         AggregationBuilders.terms("brand").field("brand")  
       )
     )
  );
like image 34
Xavier Portebois Avatar answered Oct 03 '22 03:10

Xavier Portebois