diff --git a/package.json b/package.json index c6f5cd0b490bb49ddd843577df4defe81fa09e15..5276081ffd28a3e7599b63629b955bf9d1512c90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jetsam-api", - "version": "2.4.0", + "version": "2.5.0", "description": "The Jetsam App API Server", "main": "server.js", "scripts": { diff --git a/src/domain/data/MetricsService.js b/src/domain/data/MetricsService.js index 6775c843d5c443488867d21435e9ff1476f1ec32..0cee2c510742c9ccb91b1d5670245c5793d376cd 100644 --- a/src/domain/data/MetricsService.js +++ b/src/domain/data/MetricsService.js @@ -4,9 +4,18 @@ const { User, AccessToken, Metric, Sequelize } = require('database/models') const { unset } = require('bootstrap') const HttpError = require('core/errors/HttpError') const moment = require("moment"); +const InputValidationError = require("../../core/errors/InputValidationError"); const { Op } = Sequelize +const aggregateTypeMap = { + count: 'COUNT', + min: 'MIN', + max: 'MAX', + sum: 'SUM', + average: 'AVG', +} + module.exports = class MetricsService extends ContextualModule { static getServiceName() { return 'data.metrics' @@ -54,8 +63,13 @@ module.exports = class MetricsService extends ContextualModule { return await Metric.create(payload, { transaction }) } - async queryAggregate(pointBuffer, types, from, to) { + async queryAggregate(pointBuffer, types, from, to, method = 'count') { const snapClause = `ST_SNAPTOGRID("Metric"."location"::geometry, 0.001)` + const aggregator = aggregateTypeMap[method] + + if (aggregator == null) { + throw new InputValidationError(['aggregate']) + } return await Metric.findAll({ where: { @@ -73,7 +87,7 @@ module.exports = class MetricsService extends ContextualModule { }, attributes: [ 'type', - [Sequelize.fn('COUNT', Sequelize.col('value')), 'value'], + [Sequelize.fn(aggregator, Sequelize.literal('"value"::numeric')), 'value'], [Sequelize.literal(snapClause), 'location'], ], group: [Sequelize.literal(snapClause), 'type'], @@ -95,6 +109,13 @@ module.exports = class MetricsService extends ContextualModule { [Op.in]: types, }, }, + attributes: [ + 'id', + 'value', + 'type', + 'location', + 'recorded_at' + ] }) } } diff --git a/src/http/controllers/api/content.js b/src/http/controllers/api/content.js index 5db0f4cd00fd50c5fba288c6a737ec5ffad3577a..1f26cd80b83f04198f21f6740dea8459335a99fa 100644 --- a/src/http/controllers/api/content.js +++ b/src/http/controllers/api/content.js @@ -120,6 +120,7 @@ exports.getWithin = async ctx => { date_to = moment.utc(), types = '', format = 'full', + aggregate = 'count', } = ctx.request.query let pointBufferData = null @@ -147,6 +148,7 @@ exports.getWithin = async ctx => { fromDate.toISOString(), // moment().subtract(12, 'months').toISOString(), toDate.toISOString(), + aggregate, ) ctx.body = { metrics }