WIP implemented date histogram
This commit is contained in:
@@ -20,6 +20,8 @@ function DataviewBackend(analysisBackend) {
|
||||
this.analysisBackend = analysisBackend;
|
||||
}
|
||||
|
||||
var DATE_AGGREGATIONS = ['minute', 'hour', 'day', 'week', 'month', 'year'];
|
||||
|
||||
module.exports = DataviewBackend;
|
||||
|
||||
DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, params, callback) {
|
||||
@@ -30,6 +32,7 @@ DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, param
|
||||
mapConfigProvider.getMapConfig(this);
|
||||
},
|
||||
function runDataviewQuery(err, mapConfig) {
|
||||
/* jshint maxcomplexity: 7 */
|
||||
assert.ifError(err);
|
||||
|
||||
var dataviewDefinition = getDataviewDefinition(mapConfig.obj(), dataviewName);
|
||||
@@ -88,6 +91,10 @@ DataviewBackend.prototype.getDataview = function (mapConfigProvider, user, param
|
||||
{ownFilter: ownFilter}
|
||||
);
|
||||
|
||||
if (params.aggregation && DATE_AGGREGATIONS.indexOf(params.aggregation) !== -1) {
|
||||
overrideParams.aggregation = params.aggregation;
|
||||
}
|
||||
|
||||
var dataview = dataviewFactory.getDataview(query, dataviewDefinition);
|
||||
dataview.getResult(pg, overrideParams, this);
|
||||
},
|
||||
|
||||
@@ -25,6 +25,7 @@ var REQUEST_QUERY_PARAMS_WHITELIST = [
|
||||
'start', // number
|
||||
'end', // number
|
||||
'column_type', // string
|
||||
'aggregation', //string
|
||||
// widgets search
|
||||
'q'
|
||||
];
|
||||
|
||||
@@ -8,7 +8,7 @@ dot.templateSettings.strip = false;
|
||||
var columnTypeQueryTpl = dot.template(
|
||||
'SELECT pg_typeof({{=it.column}})::oid FROM ({{=it.query}}) _cdb_histogram_column_type limit 1'
|
||||
);
|
||||
var columnCastTpl = dot.template("date_part('epoch', {{=it.column}})");
|
||||
// var columnCastTpl = dot.template("date_part('epoch', {{=it.column}})");
|
||||
|
||||
var BIN_MIN_NUMBER = 6;
|
||||
var BIN_MAX_NUMBER = 48;
|
||||
@@ -71,7 +71,7 @@ var overrideBinsQueryTpl = dot.template([
|
||||
var nullsQueryTpl = dot.template([
|
||||
'nulls AS (',
|
||||
' SELECT',
|
||||
' count(*) AS nulls_count',
|
||||
' count(*) AS nulls_count',
|
||||
' FROM ({{=it._query}}) _cdb_histogram_nulls',
|
||||
' WHERE {{=it._column}} IS NULL',
|
||||
')'
|
||||
@@ -97,6 +97,52 @@ var histogramQueryTpl = dot.template([
|
||||
'ORDER BY bin'
|
||||
].join('\n'));
|
||||
|
||||
var dateBasicsQueryTpl = dot.template([
|
||||
'basics AS (',
|
||||
' SELECT',
|
||||
' max(date_part(\'epoch\', {{=it._column}})) AS max_val,',
|
||||
' min(date_part(\'epoch\', {{=it._column}})) AS min_val,',
|
||||
' avg(date_part(\'epoch\', {{=it._column}})) AS avg_val,',
|
||||
' min(date_trunc(\'{{=it._aggregation}}\', {{=it._column}})) AS start_date,',
|
||||
' max({{=it._column}}) AS end_date,',
|
||||
' count(1) AS total_rows',
|
||||
' FROM ({{=it._query}}) _cdb_basics',
|
||||
')'
|
||||
].join(' \n'));
|
||||
|
||||
var dateBinsQueryTpl = dot.template([
|
||||
'bins AS (',
|
||||
' SELECT',
|
||||
' bins_array,',
|
||||
' ARRAY_LENGTH(bins_array, 1) AS bins_number',
|
||||
' FROM (',
|
||||
' SELECT',
|
||||
' ARRAY(',
|
||||
' SELECT GENERATE_SERIES(start_date, end_date, \'1 {{=it._aggregation}}\'::interval)',
|
||||
' ) AS bins_array',
|
||||
' FROM basics',
|
||||
' ) _cdb_bins_array',
|
||||
')'
|
||||
].join('\n'));
|
||||
|
||||
var dateHistogramQueryTpl = dot.template([
|
||||
'SELECT',
|
||||
' (max_val - min_val) / cast(bins_number as float) AS bin_width,',
|
||||
' bins_number,',
|
||||
' nulls_count,',
|
||||
' CASE WHEN min_val = max_val',
|
||||
' THEN 0',
|
||||
' ELSE GREATEST(1, LEAST(WIDTH_BUCKET({{=it._column}}, bins_array), bins_number)) - 1',
|
||||
' END AS bin,',
|
||||
' min(date_part(\'epoch\', {{=it._column}}))::numeric AS min,',
|
||||
' max(date_part(\'epoch\', {{=it._column}}))::numeric AS max,',
|
||||
' avg(date_part(\'epoch\', {{=it._column}}))::numeric AS avg,',
|
||||
' count(*) AS freq',
|
||||
'FROM ({{=it._query}}) _cdb_histogram, basics, bins, nulls',
|
||||
'WHERE date_part(\'epoch\', {{=it._column}}) IS NOT NULL',
|
||||
'GROUP BY bin, bins_number, bin_width, nulls_count, avg_val',
|
||||
'ORDER BY bin'
|
||||
].join('\n'));
|
||||
|
||||
var TYPE = 'histogram';
|
||||
|
||||
@@ -118,6 +164,7 @@ function Histogram(query, options, queries) {
|
||||
this.queries = queries;
|
||||
this.column = options.column;
|
||||
this.bins = options.bins;
|
||||
this.aggregation = options.aggregation;
|
||||
|
||||
this._columnType = null;
|
||||
}
|
||||
@@ -163,7 +210,7 @@ Histogram.prototype.sql = function(psql, override, callback) {
|
||||
}
|
||||
|
||||
if (this._columnType === 'date') {
|
||||
_column = columnCastTpl({column: _column});
|
||||
return this._buildDateHistogramQuery(override, callback);
|
||||
}
|
||||
|
||||
var _query = this.query;
|
||||
@@ -211,7 +258,6 @@ Histogram.prototype.sql = function(psql, override, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var histogramSql = [
|
||||
"WITH",
|
||||
[
|
||||
@@ -233,6 +279,48 @@ Histogram.prototype.sql = function(psql, override, callback) {
|
||||
return callback(null, histogramSql);
|
||||
};
|
||||
|
||||
Histogram.prototype._buildDateHistogramQuery = function (override, callback) {
|
||||
var _column = this.column;
|
||||
var _query = this.query;
|
||||
var _aggregation = override && override.aggregation ? override.aggregation : this.aggregation;
|
||||
|
||||
var dateBasicsQuery = dateBasicsQueryTpl({
|
||||
_query: _query,
|
||||
_column: _column,
|
||||
_aggregation: _aggregation
|
||||
});
|
||||
|
||||
var dateBinsQuery = [
|
||||
dateBinsQueryTpl({
|
||||
_aggregation: _aggregation
|
||||
})
|
||||
].join(',\n');
|
||||
|
||||
var nullsQuery = nullsQueryTpl({
|
||||
_query: _query,
|
||||
_column: _column
|
||||
});
|
||||
|
||||
var dateHistogramQuery = dateHistogramQueryTpl({
|
||||
_query: _query,
|
||||
_column: _column
|
||||
});
|
||||
|
||||
var histogramSql = [
|
||||
"WITH",
|
||||
[
|
||||
dateBasicsQuery,
|
||||
dateBinsQuery,
|
||||
nullsQuery
|
||||
].join(',\n'),
|
||||
dateHistogramQuery
|
||||
].join('\n');
|
||||
|
||||
debug(histogramSql);
|
||||
|
||||
return callback(null, histogramSql);
|
||||
};
|
||||
|
||||
Histogram.prototype.format = function(result, override) {
|
||||
override = override || {};
|
||||
var buckets = [];
|
||||
|
||||
Reference in New Issue
Block a user