Implemented topN query type, refactored querySrv

This commit is contained in:
Rashid Khan 2013-10-22 15:29:26 -07:00
parent 867bfbeddb
commit 6a93e72a34
15 changed files with 125 additions and 105 deletions

View File

@ -13,8 +13,15 @@ function (angular) {
'<div class="row-fluid panel-extra"><div class="panel-extra-container">' +
'<span class="extra row-button" ng-show="panel.editable != false">' +
'<span confirm-click="row.panels = _.without(row.panels,panel)" '+
'confirmation="Are you sure you want to remove this {{panel.type}} panel?" class="pointer">'+
'<i class="icon-remove pointer" bs-tooltip="\'Remove\'"></i></span>'+
'</span>' +
'<span class="extra row-button" ng-hide="panel.draggable == false">' +
'<span class="row-text pointer" bs-tooltip="\'Drag here to move\'"' +
'<span class="pointer" bs-tooltip="\'Drag here to move\'"' +
'data-drag=true data-jqyoui-options="{revert: \'invalid\',helper:\'clone\'}"'+
' jqyoui-draggable="'+
'{'+
@ -23,18 +30,12 @@ function (angular) {
'index:{{$index}},'+
'onStart:\'panelMoveStart\','+
'onStop:\'panelMoveStop\''+
'}" ng-model="row.panels">{{panel.type}}</span>'+
'}" ng-model="row.panels"><i class="icon-move"></i></span>'+
'</span>' +
'<span class="extra row-button" ng-show="panel.draggable == false">' +
'<span class="row-text">{{panel.type}}</span>'+
'</span>' +
'<span class="extra row-button" ng-show="panel.editable != false">' +
'<span confirm-click="row.panels = _.without(row.panels,panel)" '+
'confirmation="Are you sure you want to remove this {{panel.type}} panel?" class="pointer">'+
'<i class="icon-remove pointer" bs-tooltip="\'Remove\'"></i></span>'+
'</span>' +
'<span class="row-button extra" ng-show="panel.editable != false">' +
'<span bs-modal="\'app/partials/paneleditor.html\'" class="pointer">'+
'<i class="icon-cog pointer" bs-tooltip="\'Configure\'"></i></span>'+

View File

@ -101,10 +101,11 @@ function (angular, app, _, L, localRequire) {
var _segment = _.isUndefined(segment) ? 0 : segment;
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
// This could probably be changed to a BoolFilter
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
var boolQuery = $scope.ejs.BoolQuery();
_.each($scope.panel.queries.ids,function(id) {
boolQuery = boolQuery.should(querySrv.getEjsObj(id));
_.each(queries,function(q) {
boolQuery = boolQuery.should(querySrv.toEjsObj(q));
});
var request = $scope.ejs.Request().indices(dashboard.indices[_segment])

View File

@ -63,12 +63,6 @@
Lines
</label>
</div>
<div class="checkbox">
<label class="small">
<input type="checkbox" ng-model="panel.points" ng-checked="panel.points" ng-change="render()">
Points
</label>
</div>
<div class="checkbox">
<label class="small">
<input type="checkbox" ng-model="panel.stack" ng-checked="panel.stack" ng-change="render()">
@ -84,6 +78,14 @@
</label>
</div>
</span>
<span>
<div class="checkbox">
<label class="small">
<input type="checkbox" ng-model="panel.legend" ng-checked="panel.legend" ng-change="render()">
Legend
</label>
</div>
</span>
<span>
<label class="small">Interval</label> <select ng-change="set_interval(panel.interval);get_data();" class="input-small" ng-model="panel.interval" ng-options="interval_label(time) for time in _.union([panel.interval],panel.intervals)"></select>
</span>

View File

@ -84,14 +84,16 @@ define([
var request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
// Build the question part of the query
_.each($scope.panel.queries.ids, function(id) {
_.each(queries, function(q) {
var _q = $scope.ejs.FilteredQuery(
querySrv.getEjsObj(id),
querySrv.toEjsObj(q),
filterSrv.getBoolFilter(filterSrv.ids));
request = request
.facet($scope.ejs.QueryFacet(id)
.facet($scope.ejs.QueryFacet(q.id)
.query(_q)
).size(0);
});
@ -117,24 +119,19 @@ define([
return;
}
// Convert facet ids to numbers
var facetIds = _.map(_.keys(results.facets),function(k){return parseInt(k, 10);});
// Make sure we're still on the same query/queries
if($scope.query_id === query_id &&
_.intersection(facetIds,$scope.panel.queries.ids).length === $scope.panel.queries.ids.length
) {
if($scope.query_id === query_id) {
var i = 0;
_.each($scope.panel.queries.ids, function(id) {
var v = results.facets[id];
_.each(queries, function(q) {
var v = results.facets[q.id];
var hits = _.isUndefined($scope.data[i]) || _segment === 0 ?
v.count : $scope.data[i].hits+v.count;
$scope.hits += v.count;
// Create series
$scope.data[i] = {
info: querySrv.list[id],
id: id,
info: q,
id: q.id,
hits: hits,
data: [[i,hits]]
};

View File

@ -76,14 +76,17 @@ function (angular, app, _, $) {
$scope.panelMeta.loading = true;
var request;
request = $scope.ejs.Request().indices(dashboard.indices);
var request,
boolQuery,
queries;
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
// This could probably be changed to a BoolFilter
var boolQuery = $scope.ejs.BoolQuery();
_.each($scope.panel.queries.ids,function(id) {
boolQuery = boolQuery.should(querySrv.getEjsObj(id));
request = $scope.ejs.Request().indices(dashboard.indices);
queries = querySrv.getQueryObjs($scope.panel.queries.ids);
boolQuery = $scope.ejs.BoolQuery();
_.each(queries,function(q) {
boolQuery = boolQuery.should(querySrv.toEjsObj(q));
});
// Then the insert into facet and make the request

View File

@ -109,13 +109,14 @@ define([
var request = $scope.ejs.Request().indices(dashboard.indices);
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
// This could probably be changed to a BoolFilter
var boolQuery = $scope.ejs.BoolQuery();
_.each($scope.panel.queries.ids,function(id) {
boolQuery = boolQuery.should(querySrv.getEjsObj(id));
_.each(queries,function(q) {
boolQuery = boolQuery.should(querySrv.toEjsObj(q));
});
var results;
// Terms mode

View File

@ -111,7 +111,6 @@ function (angular, app, _, kbn, moment) {
};
var showModal = function(panel,type) {
$scope.facetPanel = panel;
$scope.facetType = type;
@ -221,16 +220,17 @@ function (angular, app, _, kbn, moment) {
$scope.panelMeta.loading = true;
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
_segment = _.isUndefined(segment) ? 0 : segment;
$scope.segment = _segment;
request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
boolQuery = $scope.ejs.BoolQuery();
_.each($scope.panel.queries.ids,function(id) {
boolQuery = boolQuery.should(querySrv.getEjsObj(id));
_.each(queries,function(q) {
boolQuery = boolQuery.should(querySrv.toEjsObj(q));
});
request = request.query(

View File

@ -83,17 +83,21 @@ function (angular, app, _, $, kbn) {
$scope.panelMeta.loading = true;
var request,
results,
boolQuery;
boolQuery,
queries;
request = $scope.ejs.Request().indices(dashboard.indices);
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
queries = querySrv.getQueryObjs($scope.panel.queries.ids);
// This could probably be changed to a BoolFilter
boolQuery = $scope.ejs.BoolQuery();
_.each($scope.panel.queries.ids,function(id) {
boolQuery = boolQuery.should(querySrv.getEjsObj(id));
_.each(queries,function(q) {
boolQuery = boolQuery.should(querySrv.toEjsObj(q));
});
// Terms mode
request = request
.facet($scope.ejs.TermsFacet('terms')

View File

@ -1,11 +1,17 @@
<div ng-controller='trends' ng-init="init()">
<div ng-style="panel.style" style="line-height:{{panel.style['font-size']}};display:inline-block;padding-right: 5px;" ng-repeat="query in trends">
<style>
div.trends-horizontal {
display:inline-block;
padding-right: 5px;
}
</style>
<div ng-class="{'trends-horizontal':panel.arrangement == 'horizontal'}" ng-style="panel.style" style="line-height:{{panel.style['font-size']}};" ng-repeat="query in trends">
<i class="icon-circle" style="color:{{query.info.color}}"></i>
<span bs-tooltip="'Then: '+query.hits.old+', Now: '+query.hits.new" ng-class="{'text-success': query.hits.new >= query.hits.old, 'text-error': query.hits.old > query.hits.new}" class='pointer strong'>
<i class='large' ng-class="{'icon-caret-up': query.hits.new >= query.hits.old, 'icon-caret-down': query.hits.old > query.hits.new}"></i> {{query.percent}}%
</span>
<span class="tiny light" ng-show="query.info.alias != ''">({{query.info.alias}})</span>
<br ng-show="panel.arrangement == 'vertical'">
</div>
</div>

View File

@ -73,8 +73,6 @@ function (angular, app, _, kbn) {
$scope.index = segment > 0 ? $scope.index : dashboard.indices;
}
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
// Determine a time field
var timeField = _.uniq(_.pluck(filterSrv.getByType('time'),'field'));
if(timeField.length > 1) {
@ -98,11 +96,13 @@ function (angular, app, _, kbn) {
var request = $scope.ejs.Request();
var _ids_without_time = _.difference(filterSrv.ids,filterSrv.idsByType('time'));
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
// Build the question part of the query
_.each($scope.panel.queries.ids, function(id) {
_.each(queries, function(query) {
var q = $scope.ejs.FilteredQuery(
querySrv.getEjsObj(id),
querySrv.toEjsObj(query),
filterSrv.getBoolFilter(_ids_without_time).must(
$scope.ejs.RangeFilter(timeField)
.from($scope.time.from)
@ -110,23 +110,23 @@ function (angular, app, _, kbn) {
));
request = request
.facet($scope.ejs.QueryFacet(id)
.facet($scope.ejs.QueryFacet(query.id)
.query(q)
).size(0);
});
// And again for the old time period
_.each($scope.panel.queries.ids, function(id) {
_.each(queries, function(query) {
var q = $scope.ejs.FilteredQuery(
querySrv.getEjsObj(id),
querySrv.toEjsObj(query),
filterSrv.getBoolFilter(_ids_without_time).must(
$scope.ejs.RangeFilter(timeField)
.from($scope.old_time.from)
.to($scope.old_time.to)
));
request = request
.facet($scope.ejs.QueryFacet("old_"+id)
.facet($scope.ejs.QueryFacet("old_"+query.id)
.query(q)
).size(0);
});
@ -169,17 +169,14 @@ function (angular, app, _, kbn) {
return;
}
// Convert facet ids to numbers
var facetIds = _.map(_.keys(results.facets),function(k){if(!isNaN(k)){return parseInt(k, 10);}});
// Make sure we're still on the same query/queries
if($scope.query_id === query_id &&
_.intersection(facetIds,$scope.panel.queries.ids).length === $scope.panel.queries.ids.length
) {
if($scope.query_id === query_id) {
var i = 0;
_.each($scope.panel.queries.ids, function(id) {
var n = results.facets[id].count;
var o = results.facets['old_'+id].count;
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
_.each(queries, function(query) {
var n = results.facets[query.id].count;
var o = results.facets['old_'+query.id].count;
var hits = {
new : _.isUndefined($scope.data[i]) || _segment === 0 ? n : $scope.data[i].hits.new+n,
@ -193,7 +190,7 @@ function (angular, app, _, kbn) {
'?' : Math.round(percentage(hits.old,hits.new)*100)/100;
// Create series
$scope.data[i] = {
info: querySrv.list[id],
info: query,
hits: {
new : hits.new,
old : hits.old

View File

@ -16,7 +16,7 @@
</div>
<div class="span9 querySelect" ng-show="panel.queries.mode == 'selected'">
<label class="small">Selected Queries</label>
<span ng-style="{'border-color': querySrv.list[id].color}" ng-class="{selected:_.contains(panel.queries.ids,id),unselected:!_.contains(panel.queries.ids,id)}" ng-repeat="id in querySrv.getIds()" ng-click="panel.queries.ids = _.toggleInOut(panel.queries.ids,id);set_refresh(true);" class="query pointer badge">
<span ng-style="{'border-color': querySrv.list[id].color}" ng-class="{selected:_.contains(panel.queries.ids,id),unselected:!_.contains(panel.queries.ids,id)}" ng-repeat="id in querySrv.ids" ng-click="panel.queries.ids = _.toggleInOut(panel.queries.ids,id);set_refresh(true);" class="query pointer badge">
<i class="icon-circle" ng-style="{color: querySrv.list[id].color}"></i>
<span> {{querySrv.list[id].alias || querySrv.list[id].query}}</span>
</span>

View File

@ -51,10 +51,11 @@ function (angular, _, config, kbn) {
"regex": {
query: ".*"
},
"derive": {
"topN": {
query: "*",
field: "_type",
size: "5"
size: 5,
union: 'AND'
}
};
@ -79,41 +80,46 @@ function (angular, _, config, kbn) {
p.resolve(_.extend(query,{parent:query.id}));
return p.promise;
}
}
};
},
topN : {
require:">=0.90.3",
icon: "icon-cog",
resolve: function(q) {
var suffix = '';
if (q.union === 'AND') {
suffix = ' AND (' + (q.query||'*') + ')';
} else if (q.union === 'OR') {
suffix = ' OR (' + (q.query||'*') + ')';
}
this.queryTypes.derive = {
require:">=0.90.3",
icon: "icon-cog",
resolve: function(q) {
var request = ejs.Request().indices(dashboard.indices);
var field = "extension";
// Terms mode
request = request
.facet(ejs.TermsFacet('query')
.field(field)
.size(10)
.facetFilter(ejs.QueryFilter(
ejs.FilteredQuery(
ejs.QueryStringQuery(q.query || '*'),
filterSrv.getBoolFilter(filterSrv.ids)
)))).size(0);
var request = ejs.Request().indices(dashboard.indices);
// Terms mode
request = request
.facet(ejs.TermsFacet('query')
.field(q.field)
.size(q.size)
.facetFilter(ejs.QueryFilter(
ejs.FilteredQuery(
ejs.QueryStringQuery(q.query || '*'),
filterSrv.getBoolFilter(filterSrv.ids)
)))).size(0);
var results = request.doSearch();
return results.then(function(data) {
var _colors = kbn.colorSteps(q.color,data.facets.query.terms.length);
var i = -1;
return _.map(data.facets.query.terms,function(t) {
++i;
return self.defaults({
query : field+":"+t.term+" AND ("+q.query+")",
alias : t.term + (q.alias ? " ("+q.alias+")" : ""),
type : 'lucene',
color : _colors[i],
parent : q.id
var results = request.doSearch();
return results.then(function(data) {
var _colors = kbn.colorSteps(q.color,data.facets.query.terms.length);
var i = -1;
return _.map(data.facets.query.terms,function(t) {
++i;
return self.defaults({
query : q.field+':"'+t.term+'"'+suffix,
alias : t.term + (q.alias ? " ("+q.alias+")" : ""),
type : 'lucene',
color : _colors[i],
parent : q.id
});
});
});
});
}
}
};
@ -223,8 +229,6 @@ function (angular, _, config, kbn) {
// This populates the internal query list and returns a promise containing it
this.resolve = function() {
// Find ids of all abstract queries
console.log("keys: "+_.keys(self.list));
console.log("ids : "+_.pluck(self.list,'id'));
// Get a list of resolvable ids, constrast with total list to get abstract ones
return $q.all(_.map(self.ids,function(q) {
return self.queryTypes[self.list[q].type].resolve(_.clone(self.list[q])).then(function(data){

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -16,6 +16,10 @@ div.fake-input {
.border-radius(@inputBorderRadius @inputBorderRadius @inputBorderRadius @inputBorderRadius);
}
hr.small {
margin: 5px 0px;
}
form input.ng-invalid {
color: @errorText;
}