0

I'm trying to group search results from Haystack. I want them to be grouped by model (Artist or Painting), then by a date field (created), then ideally by a boolean field (sold).

I.e. something like the following but it's not working. I think I need to override SearchView and somehow process the query before it's handed to the template but I'm not sure how.

Or perhaps I should just be doing the grouping in the template?

def get_queryset():
    q = SearchQuerySet().filter(display=True).order_by('-created')

    paintings_unsold = q.models(Painting).filter(sold=False)
    paintings_sold = q.models(Painting).filter(sold=True)
    artists = q.models(Artist)

    return paintings_unsold | paintings_sold | artists


urlpatterns += patterns(
    '',
    (r'^search/', SearchView(
         searchqueryset=get_queryset()
    ))
)
j0k
  • 22,600
  • 28
  • 79
  • 90
eggbert
  • 3,105
  • 5
  • 30
  • 39
  • Not sure what you mean by "group by". A searchview result set is a list of items. Maybe you mean 'facets'? – Hamish Oct 14 '13 at 22:58
  • I think I mean that instead of returning search results in the order of relevance (which I presume they are by default), I want to return them by underlying model type, then by a boolean attribute on that model. – eggbert Oct 15 '13 at 08:55
  • Still not sure what you mean. You're talking about a *sorting order*, which is quite different from grouping. – Hamish Oct 16 '13 at 00:50
  • why not just make 3 requests? – dalore Mar 24 '14 at 18:07
  • I feel like faceting would give you the groups you're looking for. I don't know how you would order like that though. It seems to contradict the nature of search results. You can boost certain fields so that when matched on that field they would appear higher in the search results. However, it sounds more like you want to do a filter, and then do some order_bys. – user133688 May 22 '14 at 23:49

1 Answers1

0

Just to clarify that facetting is not equal to grouping results. SOLR can do this, for example (Version 4): https://cwiki.apache.org/confluence/display/solr/Result+Grouping.

But what you are actually asking for is faceting, as mentioned in the comments:

http://django-haystack.readthedocs.org/en/v2.4.0/faceting.html https://cwiki.apache.org/confluence/display/solr/Faceting

I will provide an answer for SOLR, even thought the question is tagged with Whoosh. It might still help.


You want to facet on the field sold and a field artist_exact that you will probably have to create. It has to be of type string otherwise your facets will look odd.

So, your current artist field is probably (recommended) a text field that tokenizes the input somehow. Simply add a new field that does not tokenize and a copy directive in schema.xml that copies the artist to this new field.

<field name="artist" type="text_general" indexed="true" stored="true"/>
<field name="artist_exact" type="string" indexed="true" stored="false"/>
<copyField source="artist" dest="artist_exact" />

In solrconfig.xml add the following parameters to your search handler:

<str name="facet">on</str>
<str name="facet.field">sold</str>
<str name="facet.field">artist_exact</str>

Haystack provides the FacetedSearchView that you can use. It will add the facet information to the template context.

Risadinha
  • 16,058
  • 2
  • 88
  • 91