瀏覽代碼

[search] Adding some facets

Romain Rigaux 13 年之前
父節點
當前提交
fe22573

+ 3 - 1
apps/search/src/search/forms.py

@@ -20,4 +20,6 @@ from django import forms
 
 
 
 
 class QueryForm(forms.Form):
 class QueryForm(forms.Form):
-  query = forms.CharField(label="", max_length=256, required=False, widget=forms.TextInput(attrs={'class': 'input-xxlarge search-query', 'placeholder': 'e.g. solr or video'}))
+  query = forms.CharField(label='', max_length=256, required=False, initial='',
+                          widget=forms.TextInput(attrs={'class': 'input-xxlarge search-query', 'placeholder': 'e.g. solr or video'}))
+  fq = forms.CharField(label='', max_length=256, required=False, initial='', widget=forms.HiddenInput(), help_text='Solr Filter query')

+ 38 - 39
apps/search/src/search/templates/index.mako

@@ -13,32 +13,17 @@
 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ## See the License for the specific language governing permissions and
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ## limitations under the License.
+
 <%!
 <%!
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from itertools import izip
 from itertools import izip
 %>
 %>
 
 
-
-
-<%
-def pairwise(iterable):
-    "s -> (s0,s1), (s2,s3), (s4, s5), ..."
-    a = iter(iterable)
-    return izip(a, a)
-%>
+<%namespace name="macros" file="macros.mako" />
 
 
 ${ commonheader(_('Search'), "search", user) }
 ${ commonheader(_('Search'), "search", user) }
 
 
-
-##<div class="subnav subnav-fixed">
-##  <div class="container-fluid">
-##    <ul class="nav nav-pills">
-##	  <li><a href="">${_('Configuration')}</a></li>
-##    </ul>
-##  </div>
-##</div>
-
 <div class="container-fluid">
 <div class="container-fluid">
     <div class="row-fluid">
     <div class="row-fluid">
         <div class="span3">
         <div class="span3">
@@ -46,24 +31,52 @@ ${ commonheader(_('Search'), "search", user) }
             <ul class="nav nav-list">
             <ul class="nav nav-list">
                 % if response and response['facet_counts']:
                 % if response and response['facet_counts']:
                     % if response['facet_counts']['facet_fields']:
                     % if response['facet_counts']['facet_fields']:
-                        <h4>Field Facets</h4>
+                        <h4>Fields</h4>
                         % for cat in response['facet_counts']['facet_fields']:
                         % for cat in response['facet_counts']['facet_fields']:
                             % if response['facet_counts']['facet_fields'][cat]:
                             % if response['facet_counts']['facet_fields'][cat]:
                             <li class="nav-header">${cat}</li>
                             <li class="nav-header">${cat}</li>
-                            % for subcat, count in pairwise(response['facet_counts']['facet_fields'][cat]):
-                                <li><a href="#">${subcat} (${count})</a></li>
+                            % for subcat, count in macros.pairwise(response['facet_counts']['facet_fields'][cat]):
+                                <li><a href="?query=${ solr_query['q'] }&fq=${ cat }:${ subcat }">${ subcat } (${ count })</a></li>
                             % endfor
                             % endfor
                             % endif
                             % endif
                         % endfor
                         % endfor
                     %endif
                     %endif
+
                     % if response['facet_counts']['facet_queries']:
                     % if response['facet_counts']['facet_queries']:
-                        <h4>Query Facets</h4>
+                        ## Not used in demo
+                        <h4>Queries</h4>
                         % for cat in response['facet_counts']['facet_queries']:
                         % for cat in response['facet_counts']['facet_queries']:
                             % if response['facet_counts']['facet_queries'][cat]:
                             % if response['facet_counts']['facet_queries'][cat]:
                                 <li><a href="#">${cat} (${response['facet_counts']['facet_queries'][cat]})</a></li>
                                 <li><a href="#">${cat} (${response['facet_counts']['facet_queries'][cat]})</a></li>
                             % endif
                             % endif
                         % endfor
                         % endfor
                     %endif
                     %endif
+
+                    % if response['facet_counts']['facet_ranges']:
+                        <h4>Ranges</h4>
+                        % for cat in response['facet_counts']['facet_ranges']:
+                            % if response['facet_counts']['facet_ranges'][cat]:
+                            <li class="nav-header">${cat}</li>
+                            % for range, count in macros.pairwise(response['facet_counts']['facet_ranges'][cat]['counts']):
+                                <li><a href="?query=${ solr_query['q'] }&fq=${ cat }:${ range }">${ range } (${ count })</a></li>
+                            % endfor
+                            % endif
+                        % endfor
+                    %endif
+
+                    % if response['facet_counts']['facet_dates']:
+                        <h4>Dates</h4>
+                        % for cat in response['facet_counts']['facet_dates']:
+                            % if response['facet_counts']['facet_dates'][cat]:
+                            <li class="nav-header">${cat}</li>
+                            % for date, count in response['facet_counts']['facet_dates'][cat].iteritems():
+                              % if date not in ('start', 'end', 'gap'):
+                                <li><a href="?query=${ solr_query['q'] }&fq=${ cat }:${ date }">${ date } (${ count })</a></li>
+                              % endif
+                            % endfor
+                            % endif
+                        % endfor
+                    %endif
                 %endif
                 %endif
             </ul>
             </ul>
             </div>
             </div>
@@ -78,24 +91,7 @@ ${ commonheader(_('Search'), "search", user) }
                 <table class="table table-striped table-hover" style="table-layout: fixed;">
                 <table class="table table-striped table-hover" style="table-layout: fixed;">
                 <tbody>
                 <tbody>
                 % for result in response['response']['docs']:
                 % for result in response['response']['docs']:
-                <tr>
-                    <td style="word-wrap: break-word;">
-                        <a rel="nofollow" href="#"><b>${ result.get('name', '') }</b></a>
-                        <p>Price: ${ result.get('price_c', '') }</p>
-                        <p>
-                        % if result.get('features'):
-                            <ul>
-                            % for feature in result.get('features', ''):
-                                <li>${ feature }</li>
-                            % endfor
-                            </ul>
-                        % endif
-                        </p>
-                        <div style="color: #46a546;">
-                            Id: ${ result.get('id', '') }
-                        </div>
-                    </td>
-                </tr>
+                    ${ macros.tweet_result(result) }
                 % endfor
                 % endfor
                 </tbody>
                 </tbody>
                 </table>
                 </table>
@@ -105,7 +101,10 @@ ${ commonheader(_('Search'), "search", user) }
             % endif
             % endif
         </div>
         </div>
     </div>
     </div>
+</div>
 
 
+<div class="hide">
+    ${ rr }
 </div>
 </div>
 
 
 ${ commonfooter(messages) }
 ${ commonfooter(messages) }

+ 66 - 0
apps/search/src/search/templates/macros.mako

@@ -0,0 +1,66 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+<%!
+from django.utils.translation import ugettext as _
+from itertools import izip
+%>
+
+
+
+<%def name="pairwise(iterable)">
+  ##"s -> (s0,s1), (s2,s3), (s4, s5), ..."
+  <%
+    a = iter(iterable)
+    return izip(a, a)
+  %>
+</%def>
+
+
+<%def name="tweet_result(result)">
+<tr>
+    <td style="word-wrap: break-word;">
+        ## TODO on hover username popover
+        <div id="${ 'user-%s' % result.get('id', '') }" class="hide">
+            ${ result.get('user_screen_name', '') } @${ result.get('user_name', '') }
+
+            Description: ${ result.get('user_description', '') }
+            Location: ${ result.get('user_location', '') }
+
+            User tweets #: ${ result.get('user_statuses_count', '') }
+            User followers #: ${ result.get('user_followers_count', '') }
+        </div>
+
+        <a rel="nofollow" href="https://twitter.com/${ result.get('user_screen_name', '') }"><b>${ result.get('user_name', '') }</b></a> @${ result.get('user_name', '') }
+        <p>${ result.get('text', '') }</p>
+        <p>
+        % if result.get('features'):
+            <ul>
+            % for feature in result.get('features', ''):
+                <li>${ feature }</li>
+            % endfor
+            </ul>
+        % endif
+
+
+        </p>
+        <div style="color: #46a546;">
+            Retweet: ${ result.get('retweet_count', '') }
+            Location: ${ result.get('user_location', 'Unknown') or 'Unknown' }
+            Date ${ result.get('created_at', '') }
+        </div>
+    </td>
+</tr>
+</%def>

+ 31 - 8
apps/search/src/search/views.py

@@ -24,11 +24,9 @@ import logging
 from desktop.lib.django_util import render
 from desktop.lib.django_util import render
 
 
 from search.forms import QueryForm
 from search.forms import QueryForm
-from desktop.lib.rest.http_client import HttpClient
+from desktop.lib.rest.http_client import HttpClient, RestException
 from desktop.lib.rest.resource import Resource
 from desktop.lib.rest.resource import Resource
 
 
-from django.http import HttpResponse
-
 
 
 # http://lucene.apache.org/solr/api-4_0_0-BETA/doc-files/tutorial.html#Getting+Started
 # http://lucene.apache.org/solr/api-4_0_0-BETA/doc-files/tutorial.html#Getting+Started
 SOLR_URL = 'http://localhost:8983/solr/'
 SOLR_URL = 'http://localhost:8983/solr/'
@@ -39,12 +37,15 @@ LOG = logging.getLogger(__name__)
 def index(request):
 def index(request):
   search_form = QueryForm(request.GET)
   search_form = QueryForm(request.GET)
   response = {}
   response = {}
-  
+
   if search_form.is_valid():
   if search_form.is_valid():
-    response = SolrApi(SOLR_URL).query(search_form.cleaned_data['query'])
+    solr_query = {}
+    solr_query['q'] = search_form.cleaned_data['query']
+    solr_query['fq'] = search_form.cleaned_data['fq']
+    response = SolrApi(SOLR_URL).query(solr_query)
     response = json.loads(response)
     response = json.loads(response)
 
 
-  return render('index.mako', request, {'search_form': search_form, 'response': response, 'rr': json.dumps(response)})
+  return render('index.mako', request, {'search_form': search_form, 'response': response, 'rr': json.dumps(response), 'solr_query': solr_query})
 
 
 # Simple API for now
 # Simple API for now
 class SolrApi(object):
 class SolrApi(object):
@@ -53,5 +54,27 @@ class SolrApi(object):
     self._client = HttpClient(self._url, logger=LOG)
     self._client = HttpClient(self._url, logger=LOG)
     self._root = Resource(self._client)
     self._root = Resource(self._client)
 
 
-  def query(self, query):    
-    return self._root.get('collection1/browse', {'q': query, 'wt': 'json'})
+  def query(self, solr_query):
+    try:
+      return self._root.get('collection1/browse', (('q', solr_query['q']),
+                                                   ('fq', solr_query['fq']),
+                                                   ('wt', 'json'),
+
+                                                   ('facet', 'true'),
+                                                   ('facet.limit', 10),
+                                                   ('facet.mincount', 1),
+
+                                                   ('facet.field', 'user_location'),
+
+                                                   ('facet.range', 'retweet_count'),
+                                                   ('f.retweet_count.facet.range.start', '0'),
+                                                   ('f.retweet_count.facet.range.end', '100'),
+                                                   ('f.retweet_count.facet.range.gap', '10'),
+
+                                                   ('facet.date', 'created_at'),
+                                                   ('facet.date.start', 'NOW/DAY-305DAYS'),
+                                                   ('facet.date.end', 'NOW/DAY+1DAY'),
+                                                   ('facet.date.gap', '+1DAY')))
+    except RestException, e:
+      print e
+      return '{"responseHeader":{"status":0,"QTime":1,"params":{"wt":"json"}},"response":{"numFound":0,"start":0,"maxScore":0.0,"docs":[]},"highlighting":{}}'