Przeglądaj źródła

[search] Range select should also filter the result documents

Romain Rigaux 11 lat temu
rodzic
commit
7ee1f8b

+ 3 - 3
apps/search/src/search/api.py

@@ -216,9 +216,9 @@ class SolrApi(object):
         params += (('fq', ' '.join([urllib.unquote(utf_quoter('{!tag=%s}{!field f=%s}%s' % (fq['field'], fq['field'], _filter))) for _filter in fq['filter']])),)
       elif fq['type'] == 'range':
         # Set end range if last range
-        if fq['filter'].get('to'):
-          model_facet = [facet for facet in collection['facets'] if facet['id'] == fq['id']][0]           
-          fq['filter']['to'] = model_facet['properties']['end'] if model_facet else '*'
+#        if fq['filter'].get('to'):
+#          model_facet = [facet for facet in collection['facets'] if facet['id'] == fq['id']][0]           
+#          fq['filter']['to'] = model_facet['properties']['end'] if model_facet else '*'
         params += (('fq', urllib.unquote(utf_quoter('{!tag=%s}%s:[%s TO %s}' % (fq['field'],fq['field'], fq['filter']['from'], fq['filter']['to'])))),)
 
     if collection['template']['fieldsSelected'] and collection['template']['isGridLayout']:

+ 25 - 12
apps/search/src/search/templates/search2.mako

@@ -250,8 +250,10 @@ ${ commonheader(_('Search'), "search", user, "60px") | n,unicode }
                 <span data-bind="text: $data.value + ' (' + $data.count + ')', click: function(){ $root.query.toggleFacet({facet: $data, widget_id: $parent.id()}) }"></span>                
               <!-- /ko -->
               <!-- ko if: $data.selected -->
-                <span data-bind="text: $data.value, click: function(){ $root.query.toggleFacet({facet: $data, widget_id: $parent.id()}) }"></span>
-                <i class="fa fa-times"></i>
+                <span data-bind="click: function(){ $root.query.toggleFacet({facet: $data, widget_id: $parent.id()}) }">
+                  <span data-bind="text: $data.value"></span>
+                  <i class="fa fa-times"></i>
+                </span>
               <!-- /ko -->
             </a>
           </div>
@@ -260,14 +262,16 @@ ${ commonheader(_('Search'), "search", user, "60px") | n,unicode }
 	    <!-- ko if: type() == 'range' -->
         <div data-bind="foreach: $parent.counts">
           <div>
-            <a href="script:void(0)">
+            <a href="">
               <!-- ko if: ! selected --> 
                 <span data-bind="text: $data.from + ' - ' + $data.to + ' (' + $data.value + ')',
                   click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }"></span>                
               <!-- /ko -->
               <!-- ko if: selected -->
-                <span data-bind="text: $data.from + ' - ' + $data.to, click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }"></span>
-                <i class="fa fa-times"></i>
+                <span data-bind="click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }">
+                  <span data-bind="text: $data.from + ' - ' + $data.to"></span>
+                  <i class="fa fa-times"></i>
+                </span>
               <!-- /ko -->
             </a>
           </div>
@@ -397,11 +401,15 @@ ${ commonheader(_('Search'), "search", user, "60px") | n,unicode }
 
     ##<a href="javascript:void(0)"><i class="fa fa-plus"></i></a>
     <a href="javascript:void(0)" data-bind="click: $root.collection.timeLineZoom"><i class="fa fa-minus"></i></a>
-    ## <span data-bind="text: ko.mapping.toJSON(extraSeries)"></span>
+    <span>
+      Group By
+      <select data-bind="options: $root.query.multiqs, optionsText: 'label', value: $root.query.selectedMultiq">
+      </select>      
+    </span>
 
     <div data-bind="timelineChart: {datum: {counts: counts, extraSeries: extraSeries, widget_id: $parent.id(), label: label}, field: field, label: label, transformer: timelineChartDataTransformer,
-      onSelectRange: function(from, to){viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: $parent.id()})},
-      onComplete: function(){viewModel.getWidgetById(id).isLoading(false)}}" />
+      onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: $parent.id()}) },
+      onComplete: function(){ viewModel.getWidgetById(id).isLoading(false) }}" />
   </div>
   <!-- /ko -->
 </script>
@@ -474,6 +482,10 @@ ${ commonheader(_('Search'), "search", user, "60px") | n,unicode }
   <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
     <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
       ${ _('Label') }: <input type="text" data-bind="value: label" />
+      <br/>      
+      ${ _('Start') }: <input type="text" data-bind="value: properties.start" />
+      ${ _('End') }: <input type="text" data-bind="value: properties.end" />
+      ${ _('Gap') }: <input type="text" data-bind="value: properties.gap" />      
     </div>
     <div data-bind="with: $root.collection.getFacetById($parent.id())">
       <!-- ko if: type() == 'range' -->
@@ -912,11 +924,12 @@ function timelineChartDataTransformer(rawDatum) {
     values: _data
   });
   
-  if (rawDatum.extraSeries.length > 0) {
-  var _datum = [];
-  }
-    
+
+  // If multi query
   $(rawDatum.extraSeries).each(function (cnt, item) {
+    if (cnt == 0) {
+      _datum = [];
+    }
     var _data = [];
     $(item.counts).each(function (cnt, item) {
       _data.push({

+ 1 - 5
apps/search/src/search/views.py

@@ -503,16 +503,12 @@ def get_timeline(request):
   
   response = SolrApi(SOLR_URL.get(), request.user).query2(collection, query)
   response = augment_solr_response2(response, collection, query)
-  
-  print 'get_timeline'
-  print response['normalized_facets']
 
   result['series'] = {'label': facet_filter, 'counts': response['normalized_facets'][0]['counts']}
   result['status'] = 0
   result['message'] = ''
     
 #  except Exception, e:
-#    print e
 #    result['message'] = unicode(str(e), "utf8")
 
   return HttpResponse(json.dumps(result), mimetype="application/json")
@@ -571,7 +567,7 @@ def get_range_facet(request):
     
             
     solr_api = SolrApi(SOLR_URL.get(), request.user)
-    
+    print facet['properties']['start']
     if action == 'select':
       properties = _guess_gap(solr_api, collection, facet['field'], facet['properties']['start'], facet['properties']['end'])
     else:

+ 32 - 11
apps/search/static/js/search.ko.js

@@ -197,8 +197,27 @@ var Query = function (vm, query) {
 
   self.q = ko.observable(query.q);
   self.fqs = ko.mapping.fromJS(query.fqs);
-  // multiq?
+  var defaultMultiqGroup = {'id': null, 'label': 'query'};
+  self.multiqs = ko.computed(function () { // List of widgets supporting multiqs
+    return [defaultMultiqGroup].concat(
+    		$.map($.grep(self.fqs(), function(fq, i) {
+    			  return fq.type() == 'field';
+    		}), function(fq) {return {'id': fq.id(), 'label': fq.field()}})
+    	);
+  });
+  self.selectedMultiq = ko.observable(defaultMultiqGroup);
 
+  self.isMultiq = ko.computed(function () {
+	if (self.selectedMultiq() && self.selectedMultiq()['id'] != null) {
+      var facet = self.getFacetFilter(self.selectedMultiq()['id']);
+      return facet && facet.filter().length > 0; // todo + histogram there?
+    }
+	return false;
+  });
+  self.selectedMultiq.subscribe(function () { // To keep below the computed
+    vm.search();
+  });
+  
   self.toggleFacet = function (data) {
 	var fq = self.getFacetFilter(data.widget_id);
 
@@ -227,11 +246,11 @@ var Query = function (vm, query) {
     vm.search();
   }  
   
-  self.selectRangeFacet = function (data) { 
+  self.selectRangeFacet = function (data) {
 	var fq = self.getFacetFilter(data.widget_id);
-	var unselect = fq != null && fq.id() == data.widget_id;
+	var unselect = fq != null && fq.id() == data.widget_id && data.force == undefined;
 	
-	self.removeFilter(ko.mapping.fromJS({'id': data.widget_id})); // could combine ranges
+	self.removeFilter(ko.mapping.fromJS({'id': data.widget_id})); // TODO: could combine ranges
     
 	if (! unselect) {
       self.fqs.push(ko.mapping.fromJS({
@@ -242,7 +261,9 @@ var Query = function (vm, query) {
       }));
 	}
 
-    vm.search();
+	if (data.no_refresh == undefined) {
+      vm.search();
+	}
   }  
   
   self.removeFilter = function (data) { 
@@ -428,6 +449,8 @@ var Collection = function (vm, collection) {
 	facet.properties.start(data.from);
 	facet.properties.end(data.to);
 	
+	vm.query.selectRangeFacet({widget_id: data.widget_id, from: data.from, to: data.to, cat: data.cat, no_refresh: true, force: true});
+	
 	$.ajax({
 	  type: "POST",
 	  url: "/search/get_range_facet",	  
@@ -543,21 +566,19 @@ var SearchViewModel = function (collection_json, query_json) {
     self.isRetrievingResults(true);
     $(".jHueNotify").hide();
     
-    // Multi queries
-    var facet = self.query.getFacetFilter('4933579c-38b0-4599-afa1-021e2ca7ae1c');
+    // Multi queries    
     var multiQs = [];
 
-    // todo APPLUY FQ filter!!
-    
     // self.query.q().slice(1) too ?
-    if (facet && facet.filter().length > 0) { // todo + histogram there if set to multi q
+    if (self.query.isMultiq()) {
+      var facet = self.query.getFacetFilter(self.query.selectedMultiq()['id']);
       multiQs = $.map(facet.filter(), function(d) {
     	return $.post("/search/get_timeline", {
             collection: ko.mapping.toJSON(self.collection),
             query: ko.mapping.toJSON(self.query),
             facet: ko.mapping.toJSON(facet),
             d: d
-           }, function (data) {return data});
+          }, function (data) {return data});
       });
     }
 

+ 1 - 12
desktop/core/src/desktop/templates/common_header.mako

@@ -324,18 +324,7 @@ from django.utils.translation import ugettext as _
     <a class="brand nav-tooltip pull-left" title="${_('About Hue')}" rel="navigator-tooltip" href="/about"><img src="/static/art/hue-logo-mini-white.png" data-orig="/static/art/hue-logo-mini-white.png" data-hover="/static/art/hue-logo-mini-white-hover.png"/></a>
     % if user.is_authenticated() and section != 'login':
      <ul class="nav nav-pills pull-left">
-       <li class="dropdown">
-         <a title="${_('My documents')}" rel="navigator-tooltip" href="#" data-toggle="dropdown" class="dropdown-toggle" href="${ url('desktop.views.home') }" style="padding-bottom:2px!important">
-           <i class="fa fa-home" style="font-size: 19px"></i>
-           Home
-           <b class="caret"></b>
-         </a>       
-         <ul role="menu" class="dropdown-menu">
-           <li><a href="${ url('desktop.views.home') }"><i class="fa fa-file"></i> ${_('Documents')}</a></li>
-           <li><a href="${ url('oozie:index') }"><img src="/oozie/static/art/icon_oozie_dashboard_24.png" /> ${_('Dashboards')}</a></li>
-           <li><a href="${ url('oozie:list_workflows') }"><img src="/oozie/static/art/icon_oozie_editor_24.png" /> ${_('Reports')}</a></li>
-         </ul>
-       </li>         
+       <li><a title="${_('My documents')}" rel="navigator-tooltip" href="${ url('desktop.views.home') }" style="padding-bottom:2px!important"><i class="fa fa-home" style="font-size: 19px"></i></a></li>        
        <%
          query_apps = count_apps(apps, ['beeswax', 'impala', 'rdbms', 'pig', 'jobsub', 'spark']);
        %>