Returning only facet counts on empty search string.

211 views
Skip to first unread message

LarryEitel

unread,
Mar 23, 2010, 11:33:24 AM3/23/10
to django-haystack
I needed to find a way to present all facet counts when viewing an
intitial or empty search page. This would enable the user to find
items by drilling down by clicking on facets and/or entering search
terms.

The following is how I achieved this. Please feel free to share
suggestions for improvement.

class MySearch(FacetedSearchView):
...

def get_query(self):

if self.form.is_valid():
#
# added the following two lines.
if not self.form.cleaned_data['q']:
self.form.cleaned_data['q'] = u'*:*'

return self.form.cleaned_data['q']

return ''


class MySearchQuerySet(SearchQuerySet):
...


def auto_query(self, query_string):
#
# added the following two lines just below 'def'
if query_string == '*:*':
return self._clone()

...


LarryEitel

unread,
Mar 23, 2010, 11:42:28 AM3/23/10
to django-haystack
I thought I had it but as I work with it I discovered that while all
the facet counts appear, I cannot narrow the search based on that
facet. Looking for a solution...

Daniel Lindsley

unread,
Mar 25, 2010, 11:54:43 PM3/25/10
to django-...@googlegroups.com
Larry,


Did you get this resolved after we spoke on IRC or is this still a
problem? It should just be applying ``sqs =
SearchQuerySet().narrow('facet_fieldname:user_chosen_value')`` to
narrow things down to the selected facet(s).


Daniel

> --
> You received this message because you are subscribed to the Google Groups "django-haystack" group.
> To post to this group, send email to django-...@googlegroups.com.
> To unsubscribe from this group, send email to django-haysta...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-haystack?hl=en.
>
>

LarryEitel

unread,
Mar 26, 2010, 9:29:11 AM3/26/10
to django-haystack
Thank you Daniel. Yes it works now. The following is my views.py file
for anyone interested. Perhaps it can be further enhanced.from

django.http import HttpResponseRedirect
import re

from django.template import loader, Context
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.conf import settings

from haystack.query import EmptySearchQuerySet
from haystack.views import FacetedSearchView
from search.query import MySearchQuerySet


class MySearch(FacetedSearchView):
def __name__(self):
return "MySearch"

def __call__(self, request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
"""
Generates the actual response to the search.

Relies on internal, overridable methods to construct the
response.
"""
self.request = request
self.form = self.build_form(request.user)
self.query = self.get_query()
self.results = self.get_results()

return self.create_response()

def user_filter(self, query):
"""
narrow query based on user permission
"""
if self.request.user.id <> 1:
return query.narrow('types:nb')
else:
return query


def extra_context(self):
extra = super(MySearch, self).extra_context()

if self.query:
self.results = self.user_filter(self.results)
faceted_sqs = self.results
else:
faceted_sqs = self.searchqueryset.all()
faceted_sqs = self.user_filter(faceted_sqs)
self.results = faceted_sqs

url = self.request.get_full_path()

facets = []
for match in re.finditer(r"(?i)(&|\?)(_fq_\w+)", url):
item = match.group(2)
facet_tag = item[4:].split('___')
facets.append(facet_tag)

selected_facets = []
for facet in facets:
facet_param = "%s%s" % ('&_fq_', ('___').join(facet))
# remove facet from url so that when/if user clicks it
will REMOVE the facet from the url to remove the filter
url_without_facet = url.replace(facet_param, '')


selected_facet = {}
selected_facet['url_without_facet'] = url_without_facet
selected_facet['facet'] = facet[0]
selected_facet['tag'] = facet[1]

selected_facets.append(selected_facet)
faceted_sqs = faceted_sqs.narrow("%s:%s" % (facet[0],
facet[1]))
self.results = faceted_sqs


extra['facets'] = faceted_sqs.facet_counts()
extra['results'] = self.results.order_by('-updated_dt')
extra['count'] = len(self.results)
extra['per_page'] = settings.HAYSTACK_SEARCH_RESULTS_PER_PAGE

extra['url_without_facets'] = re.sub(r"(?i)(&|\?)_fq_\w+", "",
url)
extra['selected_facets_count'] = len(facets)
extra['selected_facets'] = selected_facets
return extra

def build_form(self, user):
"""
Instantiates the form the class should use to process the
search query.
"""
data = None
kwargs = {
'load_all': self.load_all,
}

if len(self.request.GET):
data = self.request.GET

if self.searchqueryset is not None:
kwargs['searchqueryset'] = self.searchqueryset

newdata = {}
newdata['user'] = user
if data:
for key in data.keys():
newdata[key] = data[key]

return self.form_class(newdata, **kwargs)

def create_response(self):
"""
Generates the actual HttpResponse to send back to the user.
"""
context = {
'query': self.query,
'form': self.form,
'results': self.results,
'q': self.form.fields['q'],
}
context.update(self.extra_context())
return render_to_response(self.template, context,
context_instance=self.context_class(self.request))

Reply all
Reply to author
Forward
0 new messages