Skip to content
This repository has been archived by the owner on Jul 11, 2019. It is now read-only.

Commit

Permalink
Fix facet item counts for facets with exclusive values
Browse files Browse the repository at this point in the history
The solution to calculate facet item counts for facets with exclusive
values in 9e7c7c4 was wrong and only
worked for simple cases.

The general solution in this commit instead does the following:

For each facet with exclusive values, create another solr query, which
is the same as the current main query (facet_query), but without the
filter on that same facet.

This would normally be done in solr with `LocalParams`, but this isn't
yet implemented in sunburnt (see tow/sunburnt#6). A workaround (as
described in the latter issue) would be possible if sunburnt would allow
to create multiple filter query parts instead of putting them together
in one filter query with `AND` constructs (see tow/sunburnt#37).
  • Loading branch information
nidico committed Mar 9, 2013
1 parent ab3da79 commit eb0c654
Showing 1 changed file with 47 additions and 9 deletions.
56 changes: 47 additions & 9 deletions src/adhocracy/lib/pager.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,15 @@ class SolrFacet(SolrIndexer):
>>> some_facet = SomeFacet('mypager_prefix', request)
>>> q = solr_query()
>>> counts_query = q
>>> # configure the query further
>>> q, counts_query = some_facet.add_to_queries(q, counts_query)
>>> exclusive_qs = []
>>> # configure the queries further
>>> q, counts_query, exclusive_qs = some_facet.add_to_queries(q, exclusive_qs)
>>> response = q.execute()
>>> counts_response = counts_response.execute()
>>> some_facet.update(response, counts_response)
>>> exclusive_responses = dict([counts_response = counts_response.execute()
>>> exclusive_responses = dict(map(lambda ((k, q)): (k, q.execute()),
... exclusive_qs.iteritems()))
>>> some_facet.update(response, counts_response, exclusive_responses)
>>> some_facet.items
[...]
"""
Expand Down Expand Up @@ -476,7 +480,7 @@ def get_thumbnail(self, entity):
'''
return ''

def add_to_queries(self, query, counts_query):
def add_to_queries(self, query, counts_query, exclusive_queries):
'''
Add the facet to the queries *query* and *counts_query*.
The difference is that the *query* will be limited to facet values
Expand All @@ -486,11 +490,21 @@ def add_to_queries(self, query, counts_query):
'''
query = query.facet_by(self.solr_field)
counts_query = counts_query.facet_by(self.solr_field)

if self.exclusive:
exclusive_queries[self.solr_field] =\
exclusive_queries[self.solr_field].facet_by(self.solr_field)

for value in self.used:
query = query.query(**{self.solr_field: value})
return query, counts_query

def update(self, response, counts_response):
for k, v in exclusive_queries.iteritems():
if k != self.solr_field:
exclusive_queries[k] = v.query(**{self.solr_field: value})

return query, counts_query, exclusive_queries

def update(self, response, counts_response, exclusive_responses):
'''
Compute and update different attributes of the facet based
on the solr *response* and the *base_query*.
Expand All @@ -514,6 +528,18 @@ def update(self, response, counts_response):
key=lambda(value, count): count,
reverse=True)
self.facet_counts = dict(self.sorted_facet_counts)

# the counts in the current query without the current query for this
# facet if this is an exclusive (single value) facet
if self.exclusive:
exclusive_counts = exclusive_responses[solr_field]\
.facet_counts.facet_fields[solr_field]
self.sorted_exclusive_counts = sorted(
exclusive_counts,
key=lambda(value, count): count,
reverse=True)
self.exclusive_counts = dict(self.sorted_exclusive_counts)

self.current_items = self._current_items()

# fixme: memoize
Expand Down Expand Up @@ -593,7 +619,7 @@ def show_facet(current_count, token_count, show_empty,
facet_items = OrderedDict()
for (token, token_count) in token_counts:
if self.exclusive:
current_count = self.facet_counts[token]
current_count = self.exclusive_counts[token]
else:
current_count = self.current_counts[token]

Expand Down Expand Up @@ -1084,10 +1110,18 @@ def __init__(self, name, itemfunc, entity_type=None, extra_filter=None,
# Add facets
counts_query = query
counts_query = counts_query.paginate(rows=0)

exclusive_queries = dict((f.solr_field, counts_query)
for f in self.facets if f.exclusive)

query.faceter.update(limit='65000')
counts_query.faceter.update(limit='65000')
map(lambda q: q.faceter.update(limit='65000'),
exclusive_queries.values())

for facet in self.facets:
query, counts_query = facet.add_to_queries(query, counts_query)
query, counts_query, exclusive_queries = facet.add_to_queries(
query, counts_query, exclusive_queries)

# Add pagination and sorting
if enable_pages:
Expand All @@ -1099,14 +1133,18 @@ def __init__(self, name, itemfunc, entity_type=None, extra_filter=None,
# query solr and calculate values from it
self.response = query.execute()
self.counts_response = counts_query.execute()
self.exclusive_responses = dict(map(lambda ((k, q)): (k, q.execute()),
exclusive_queries.iteritems()))

# if we are out of the page range do a permanent redirect
# to the last page
if (self.pages > 0) and (self.page > self.pages):
new_url = self.build_url(page=self.pages)
redirect(new_url, code=301)

for facet in self.facets:
facet.update(self.response, self.counts_response)
facet.update(self.response, self.counts_response,
self.exclusive_responses)
self.items = self._items_from_response(self.response)

def total_num_items(self):
Expand Down

0 comments on commit eb0c654

Please sign in to comment.