Skip to content

Commit

Permalink
Re-implement histogram panel using Aggregation API, and add uniq mode
Browse files Browse the repository at this point in the history
to search cardinality.
  • Loading branch information
chenryn committed Nov 19, 2014
1 parent 8763cad commit 6cb4d28
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/app/panels/histogram/editor.html
Expand Up @@ -3,7 +3,7 @@
<h5>Values</h5>
<div class="editor-option">
<label class="small">Chart value</label>
<select ng-change="set_refresh(true)" class="input-small" ng-model="panel.mode" ng-options="f for f in ['count','min','mean','max','total']"></select>
<select ng-change="set_refresh(true)" class="input-small" ng-model="panel.mode" ng-options="f for f in ['count','uniq','min','mean','max','total']"></select>
</div>
<div class="editor-option" ng-show="panel.mode != 'count'">
<label class="small">Value Field <tip>This field must contain a numeric value</tip></label>
Expand Down
58 changes: 33 additions & 25 deletions src/app/panels/histogram/module.js
Expand Up @@ -354,20 +354,26 @@ function (angular, app, $, _, kbn, moment, timeSeries, numeral) {
filterSrv.getBoolFilter(filterSrv.ids())
);

var facet = $scope.ejs.DateHistogramFacet(q.id);
var aggr = $scope.ejs.DateHistogramAggregation(q.id);

if($scope.panel.mode === 'count') {
facet = facet.field($scope.panel.time_field).global(true);
aggr = aggr.field($scope.panel.time_field);
} else if($scope.panel.mode === 'uniq') {
aggr = aggr.field($scope.panel.time_field).agg($scope.ejs.CardinalityAggregation(q.id).field($scope.panel.value_field));
} else {
if(_.isNull($scope.panel.value_field)) {
$scope.panel.error = "In " + $scope.panel.mode + " mode a field must be specified";
return;
}
facet = facet.keyField($scope.panel.time_field).valueField($scope.panel.value_field).global(true);
aggr = aggr.field($scope.panel.time_field).agg($scope.ejs.StatsAggregation(q.id).field($scope.panel.value_field));
}
facet = facet.interval(_interval).facetFilter($scope.ejs.QueryFilter(query));
request = request.facet(facet)
.size($scope.panel.annotate.enable ? $scope.panel.annotate.size : 0);
request = request.agg(
$scope.ejs.GlobalAggregation(q.id).agg(
$scope.ejs.FilterAggregation(q.id).filter($scope.ejs.QueryFilter(query)).agg(
aggr.interval(_interval)
)
)
).size($scope.panel.annotate.enable ? $scope.panel.annotate.size : 0);
});

if($scope.panel.annotate.enable) {
Expand Down Expand Up @@ -419,7 +425,7 @@ function (angular, app, $, _, kbn, moment, timeSeries, numeral) {
counters; // Stores the bucketed hit counts.

_.each(queries, function(q) {
var query_results = results.facets[q.id];
var query_results = results.aggregations[q.id][q.id][q.id];
// we need to initialize the data variable on the first run,
// and when we are working on the first segment of the data.
if(_.isUndefined(data[i]) || segment === 0) {
Expand All @@ -439,38 +445,40 @@ function (angular, app, $, _, kbn, moment, timeSeries, numeral) {
}

// push each entry into the time series, while incrementing counters
_.each(query_results.entries, function(entry) {
_.each(query_results.buckets, function(entry) {
var value;

hits += entry.count; // The series level hits counter
$scope.hits += entry.count; // Entire dataset level hits counter
counters[entry.time] = (counters[entry.time] || 0) + entry.count;
hits += entry.doc_count; // The series level hits counter
$scope.hits += entry.doc_count; // Entire dataset level hits counter
counters[entry.key] = (counters[entry.key] || 0) + entry.doc_count;

if($scope.panel.mode === 'count') {
value = (time_series._data[entry.time] || 0) + entry.count;
value = (time_series._data[entry.key] || 0) + entry.doc_count;
} else if ($scope.panel.mode === 'uniq') {
value = (time_series._data[entry.key] || 0) + entry[q.id].value;
} else if ($scope.panel.mode === 'mean') {
// Compute the ongoing mean by
// multiplying the existing mean by the existing hits
// plus the new mean multiplied by the new hits
// divided by the total hits
value = (((time_series._data[entry.time] || 0)*(counters[entry.time]-entry.count)) +
entry.mean*entry.count)/(counters[entry.time]);
value = (((time_series._data[entry.key] || 0)*(counters[entry.key]-entry.doc_count)) +
entry[q.id].avg*entry.doc_count)/(counters[entry.key]);
} else if ($scope.panel.mode === 'min'){
if(_.isUndefined(time_series._data[entry.time])) {
value = entry.min;
if(_.isUndefined(time_series._data[entry.key])) {
value = entry[q.id].min;
} else {
value = time_series._data[entry.time] < entry.min ? time_series._data[entry.time] : entry.min;
value = time_series._data[entry.key] < entry[q.id].min ? time_series._data[entry.key] : entry[q.id].min;
}
} else if ($scope.panel.mode === 'max'){
if(_.isUndefined(time_series._data[entry.time])) {
value = entry.max;
if(_.isUndefined(time_series._data[entry.key])) {
value = entry[q.id].max;
} else {
value = time_series._data[entry.time] > entry.max ? time_series._data[entry.time] : entry.max;
value = time_series._data[entry.key] > entry[q.id].max ? time_series._data[entry.key] : entry[q.id].max;
}
} else if ($scope.panel.mode === 'total'){
value = (time_series._data[entry.time] || 0) + entry.total;
value = (time_series._data[entry.key] || 0) + entry[q.id].sum;
}
time_series.addValue(entry.time, value);
time_series.addValue(entry.key, value);
});

$scope.legend[i] = {query:q,hits:hits};
Expand All @@ -482,10 +490,10 @@ function (angular, app, $, _, kbn, moment, timeSeries, numeral) {
counters: counters
};

var monitorTitle = $scope.panel.queries.check[i] +' for query: '+ ( queries[i].alias || queries[i].query );
if ($scope.panel.queries.check[i] === 'threshold') {
var monitorTitle = $scope.panel.queries.check[q.id] +' for query: '+ ( q.alias || q.query );
if ($scope.panel.queries.check[q.id] === 'threshold') {
monitor.check(data[i].counters, monitorTitle, $scope.panel.queries.threshold[i]);
} else if ($scope.panel.queries.check[i] === 'anomaly') {
} else if ($scope.panel.queries.check[q.id] === 'anomaly') {
monitor.check(data[i].counters, monitorTitle);
};

Expand Down

0 comments on commit 6cb4d28

Please sign in to comment.