def facet(self, field_name): # Get field field = self.query_compiler._get_filterable_field(field_name) if field is None: raise FilterFieldError( 'Cannot facet search results with field "' + field_name + '". Please add index.FilterField(\'' + field_name + '\') to ' + self.query_compiler.queryset.model.__name__ + '.search_fields.', field_name=field_name) # Build body body = self._get_es_body() column_name = self.query_compiler.mapping.get_field_column_name(field) body['aggregations'] = { field_name: { 'terms': { 'field': column_name, } } } # Send to Elasticsearch response = self.backend.es.search( index=self.backend.get_index_for_model( self.query_compiler.queryset.model).name, body=body, size=0, ) return OrderedDict([ (bucket['key'], bucket['doc_count']) for bucket in response['aggregations'][field_name]['buckets'] ])
def facet(self, field_name): # Get field field = self.query_compiler._get_filterable_field(field_name) if field is None: raise FilterFieldError( 'Cannot facet search results with field "' + field_name + '". Please add index.FilterField(\'' + field_name + '\') to ' + self.query_compiler.queryset.model.__name__ + '.search_fields.', field_name=field_name) query = self.query_compiler.search(self.backend.config, None, None) results = query.values(field_name).annotate( count=Count('pk')).order_by('-count') return OrderedDict([(result[field_name], result['count']) for result in results])
def facet(self, field_name): # Get field field = self.query_compiler._get_filterable_field(field_name) if field is None: raise FilterFieldError( 'Cannot facet search results with field "' + field_name + "\". Please add index.FilterField('" + field_name + "') to " + self.query_compiler.queryset.model.__name__ + ".search_fields.", field_name=field_name, ) query = self.get_queryset() results = (query.values(field_name).annotate( count=Count("pk")).order_by("-count")) return OrderedDict([(result[field_name], result["count"]) for result in results])
def facet(self, field_name): # Get field field = self.query_compiler._get_filterable_field(field_name) if field is None: raise FilterFieldError( 'Cannot facet search results with field "' + field_name + "\". Please add index.FilterField('" + field_name + "') to " + self.query_compiler.queryset.model.__name__ + ".search_fields.", field_name=field_name, ) # Build body body = self._get_es_body() column_name = self.query_compiler.mapping.get_field_column_name(field) body["aggregations"] = { field_name: { "terms": { "field": column_name, "missing": 0, } } } # Send to Elasticsearch response = self.backend.es.search( index=self.backend.get_index_for_model( self.query_compiler.queryset.model).name, body=body, size=0, ) return OrderedDict([ (bucket["key"] if bucket["key"] != 0 else None, bucket["doc_count"]) for bucket in response["aggregations"][field_name]["buckets"] ])
def facets(self, *field_names): "Fetches facets from ES based on the fieldnames passed" aggregations = {} for field_path in field_names: field_match = FIELD_NAME_REGEX.match(field_path) if field_match is not None: field_name = field_match.group("field_name") # Get field field = self.query_compiler._get_filterable_field( # pylint: disable=protected-access field_name ) if field is None: raise FilterFieldError( 'Cannot facet search results with field "%(field_name)s". ' 'Please add index.FilterField("%(field_name)s") to %(model_name)s.search_fields.' % { "field_name": field_name, "model_name": self.query_compiler.queryset.model.__name__, }, field_name=field_name, ) aggregations[field_path] = self._facet_to_aggregation(field_path) if aggregations: unfiltered_index = { "index": self.backend.get_index_for_model( self.query_compiler.queryset.model ).name } unfiltered_body = { "query": self.query_compiler.get_unfiltered_query(), "size": 0, } unfiltered_body["aggregations"] = aggregations filtered_index = unfiltered_index filtered_body = {"query": self.query_compiler.get_query(), "size": 0} filtered_body["aggregations"] = aggregations multi_request = [ unfiltered_index, unfiltered_body, filtered_index, filtered_body, ] # Send to Elasticsearch response = self.backend.es.msearch(body=multi_request) unfiltered_response, filtered_response = response["responses"] # handle errors gracefully if "error" in unfiltered_response: logger.error("Elasticsearch error %(error)s", unfiltered_response) return ({}, {}) return ( unfiltered_response["aggregations"], filtered_response["aggregations"], ) return {}, {}