allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brond...@apache.org
Subject [05/38] git commit: [#4019] ticket:481 Use one query for facets and search, when possible
Date Wed, 30 Apr 2014 18:15:37 GMT
[#4019] ticket:481 Use one query for facets and search, when possible

When using solr search, we could get facets and search result in one
query.

- It saves one query to solr on every request to pages with ticket list
- It returns choice options based on search result, thus options that
will produce empty result are not displayed to user, and counts are
right.

When mongo search is used (filter is not active) - fetch facets in
separate solr query.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/a90114cf
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/a90114cf
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/a90114cf

Branch: refs/heads/master
Commit: a90114cf5076e38fe716a1deb41b684f6b2ba8f1
Parents: e2cad56
Author: Igor Bondarenko <jetmind2@gmail.com>
Authored: Thu Dec 19 14:19:17 2013 +0200
Committer: Dave Brondsema <dbrondsema@slashdotmedia.com>
Committed: Wed Apr 30 15:55:09 2014 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/model/ticket.py       |  8 ++++++-
 ForgeTracker/forgetracker/search.py             | 25 ++++++++++++++------
 ForgeTracker/forgetracker/tracker_main.py       |  6 ++---
 .../forgetracker/widgets/ticket_search.py       |  5 ++--
 4 files changed, 30 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a90114cf/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 3c2e7a6..63346eb 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -69,6 +69,7 @@ from allura.lib import utils
 from allura.lib import helpers as h
 from allura.lib.plugin import ImportIdConverter
 from allura.tasks import mail_tasks
+from forgetracker import search as tsearch
 
 
 log = logging.getLogger(__name__)
@@ -1154,10 +1155,13 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             refined_sort += ',ticket_num_i asc'
         try:
             if q:
+                # also query for choices for filter options right away
+                params = kw.copy()
+                params.update(tsearch.FACET_PARAMS)
                 matches = search_artifact(
                     cls, q, short_timeout=True,
                     rows=limit, sort=refined_sort, start=start, fl='ticket_num_i',
-                    filter=filter, **kw)
+                    filter=filter, **params)
             else:
                 matches = None
             solr_error = None
@@ -1189,6 +1193,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         return dict(tickets=tickets,
                     count=count, q=q, limit=limit, page=page, sort=sort,
                     filter=json.dumps(filter),
+                    filter_choices=tsearch.get_facets(matches),
                     solr_error=solr_error, **kw)
 
     @classmethod
@@ -1207,6 +1212,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             solr_sort = '%s %s' % (solr_col, sort_split[1])
         if not filter:
             result = cls.paged_query(app_config, user, query, sort=sort, limit=limit, page=page,
**kw)
+            result['filter_choices'] = tsearch.query_filter_choices()
         else:
             result = cls.paged_search(app_config, user, search_query, filter=filter,
                                       sort=solr_sort, limit=limit, page=page, **kw)

http://git-wip-us.apache.org/repos/asf/allura/blob/a90114cf/ForgeTracker/forgetracker/search.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/search.py b/ForgeTracker/forgetracker/search.py
index 3bb5bfd..b29be6d 100644
--- a/ForgeTracker/forgetracker/search.py
+++ b/ForgeTracker/forgetracker/search.py
@@ -20,7 +20,16 @@ from pylons import tmpl_context as c
 from allura.lib.search import search
 
 
-def choices_for_filter():
+FACET_PARAMS = {
+    'facet': 'true',
+    'facet.field': ['milestone_s', 'status_s', 'assigned_to_s', 'reported_by_s'],
+    'facet.limit': -1,
+    'facet.sort': 'index',
+    'facet.mincount': 1,
+}
+
+
+def query_filter_choices():
     params = {
         'short_timeout': True,
         'fq': [
@@ -28,13 +37,15 @@ def choices_for_filter():
             'mount_point_s:%s' % c.app.config.options.mount_point
             ],
         'rows': 0,
-        'facet': 'true',
-        'facet.field': ['milestone_s', 'status_s', 'assigned_to_s', 'reported_by_s'],
-        'facet.limit': -1,
-        'facet.sort': 'index',
-        'facet.mincount': 1,
     }
+    params.update(FACET_PARAMS)
     result = search(None, **params)
+    return get_facets(result)
+
+
+def get_facets(solr_hit):
+    if solr_hit is None:
+        return {}
     def reformat(field):
         name, val = field
         name = name[:-2] if name != 'milestone_s' else '_milestone'
@@ -42,4 +53,4 @@ def choices_for_filter():
         for i in range(0, len(val), 2):
             new_val.append((val[i], val[i+1]))
         return name, new_val
-    return dict(map(reformat, result.facets['facet_fields'].iteritems()))
+    return dict(map(reformat, solr_hit.facets['facet_fields'].iteritems()))

http://git-wip-us.apache.org/repos/asf/allura/blob/a90114cf/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index eb9de0f..4618b68 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -666,7 +666,7 @@ class RootController(BaseController, FeedController):
         result['url_q'] = c.app.globals.not_closed_query
         result['deleted'] = deleted
         c.subscribe_form = W.subscribe_form
-        c.ticket_search_results = TicketSearchResults()
+        c.ticket_search_results = TicketSearchResults(result['filter_choices'])
         return result
 
     @without_trailing_slash
@@ -768,7 +768,7 @@ class RootController(BaseController, FeedController):
         result['help_msg'] = c.app.config.options.get(
             'TicketHelpSearch', '').strip()
         result['deleted'] = deleted
-        c.ticket_search_results = TicketSearchResults()
+        c.ticket_search_results = TicketSearchResults(result['filter_choices'])
         return result
 
     @with_trailing_slash
@@ -1863,6 +1863,6 @@ class MilestoneController(BaseController):
             total=progress['hits'],
             closed=progress['closed'],
             q=self.progress_key)
-        c.ticket_search_results = TicketSearchResults()
+        c.ticket_search_results = TicketSearchResults(result['filter_choices'])
         c.auto_resize_textarea = W.auto_resize_textarea
         return result

http://git-wip-us.apache.org/repos/asf/allura/blob/a90114cf/ForgeTracker/forgetracker/widgets/ticket_search.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/ticket_search.py b/ForgeTracker/forgetracker/widgets/ticket_search.py
index 65d90c4..34078b4 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_search.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_search.py
@@ -20,7 +20,6 @@ import ew.jinja2_ew as ew
 
 from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets import forms
-from forgetracker.search import choices_for_filter
 
 
 
@@ -43,12 +42,12 @@ class TicketSearchResults(ew_core.SimpleForm):
         page_size = ffw.PageSize()
         lightbox = ffw.Lightbox(name='col_list', trigger='#col_menu')
 
-    def __init__(self, *args, **kw):
+    def __init__(self, filters, *args, **kw):
         super(TicketSearchResults, self).__init__(*args, **kw)
         self.filters = {name: [{'value': val,
                             'label': '%s (%s)' % (val, count),
                             'selected': False} for val, count in field]
-                        for name, field in choices_for_filter().iteritems()}
+                        for name, field in filters.iteritems()}
 
     def resources(self):
         yield ew.JSLink('tracker_js/jquery.multiselect.min.js')


Mime
View raw message