Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #126 from openkfw/date-pointattributes
Browse files Browse the repository at this point in the history
filter point attributes by date
  • Loading branch information
MartinJurcoGlina authored Apr 29, 2022
2 parents 4d37579 + e572721 commit fb1b403
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 8 deletions.
56 changes: 54 additions & 2 deletions api/src/database/mongoDb/models/pointAttributesModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ const mongoose = require('mongoose');
const APIError = require('../../../helpers/APIError');
const { POINT_ATTRIBUTES_COLLECTION } = require('../dbSchemas/pointAttributeSchema');
const { filterCoordinates } = require('../filters');
const { dateIsValidDatum } = require('../../../helpers/utils');

const getFilteredPointAttributes = async (attributeId, bottomLeft, topRight) => {
const getFilteredPointAttributes = async (attributeId, bottomLeft, topRight, dateStart, dateEnd) => {
const { connection } = mongoose;
const { db } = connection;

Expand All @@ -15,10 +16,61 @@ const getFilteredPointAttributes = async (attributeId, bottomLeft, topRight) =>
filter['properties.attributeId'] = attributeId;
}

// date filters
if (dateStart && dateEnd) {
if (dateIsValidDatum(dateStart) && dateIsValidDatum(dateEnd)) {
if (!(new Date(dateStart) <= new Date(dateEnd))) {
throw new APIError('Invalid date format: Start date is greater than end date', 400, true);
}
filter['properties.date'] = { $gte: dateStart, $lte: dateEnd };
} else {
throw new APIError('Invalid date format', 400, true);
}
} else if (dateStart) {
if (!dateIsValidDatum(dateStart)) {
throw new APIError('Invalid date format', 400, true);
}
filter['properties.date'] = { $gte: dateStart };
} else if (dateEnd) {
if (!dateIsValidDatum(dateEnd)) {
throw new APIError('Invalid date format', 400, true);
}
filter['properties.date'] = { $lte: dateEnd };
}

const attributes = await db.collection(POINT_ATTRIBUTES_COLLECTION).find(filter).toArray();
return attributes;
};

const getLastDatePointAttributes = async (attributeId, bottomLeft, topRight) => {
const { connection } = mongoose;
const { db } = connection;

let filter = {};
if (bottomLeft && topRight) {
filter = filterCoordinates(filter, bottomLeft, topRight);
}
if (attributeId) {
filter['properties.attributeId'] = attributeId;
}

const lastDate = await db
.collection(POINT_ATTRIBUTES_COLLECTION)
.find({ 'properties.attributeId': attributeId })
.sort({ 'properties.date': -1 })
.limit(1)
.toArray();

if (!lastDate || !lastDate.length) {
throw new APIError(`Failed fetching last date for ${attributeId} in ${POINT_ATTRIBUTES_COLLECTION}`, 500, false);
}

// eslint-disable-next-line prefer-destructuring
filter['properties.date'] = lastDate[0].properties.date;
const pointAttributes = await db.collection(POINT_ATTRIBUTES_COLLECTION).find(filter).toArray();
return pointAttributes;
};

const getUniqueValues = async (attributeId, property) => {
const { connection } = mongoose;
const { db } = connection;
Expand All @@ -42,4 +94,4 @@ const getUniqueValues = async (attributeId, property) => {
return values.map((item) => item._id);
};

module.exports = { getFilteredPointAttributes, getUniqueValues };
module.exports = { getFilteredPointAttributes, getLastDatePointAttributes, getUniqueValues };
18 changes: 14 additions & 4 deletions api/src/database/pointAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,22 @@ const mongoDb = require('./mongoDb/models/pointAttributesModel');
* @param {string} attributeId
* @param {string} bottomLeft - bottom left corner, string with lon,lat divided by ','
* @param {string} topRight - top right corner, string with lon, lat divided by ','
* @param {string} dateStart - start of date interval
* @param {string} dateEnd - end of date interval
* @param {boolean} lastDate - return values in database for last date
*/
const getPointAttributes = async (attributeId, bottomLeft, topRight) => {
if (config.mongoUri) {
return mongoDb.getFilteredPointAttributes(attributeId, bottomLeft, topRight);
const getPointAttributes = async (attributeId, bottomLeft, topRight, dateStart, dateEnd, lastDate) => {
if (lastDate) {
if (config.mongoUri) {
return mongoDb.getLastDatePointAttributes(attributeId, bottomLeft, topRight);
}
throw new APIError('No connection string to database', 500, false);
} else {
if (config.mongoUri) {
return mongoDb.getFilteredPointAttributes(attributeId, bottomLeft, topRight, dateStart, dateEnd);
}
throw new APIError('No connection string to database', 500, false);
}
throw new APIError('No connection string to database', 500, false);
};

/**
Expand Down
10 changes: 10 additions & 0 deletions api/src/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ const dateIsValid = (date) => {
return false;
};

const dateIsValidDatum = (date) => {
const dateParsed = new Date(Date.parse(date));

if (dateParsed.toISOString().slice(0, 10) === date) {
return true;
}
return false;
};

module.exports = {
forwardError: (callback) => async (req, res, next) => {
try {
Expand All @@ -16,4 +25,5 @@ module.exports = {
}
},
dateIsValid,
dateIsValidDatum,
};
21 changes: 21 additions & 0 deletions api/src/openapi/apiSchema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,27 @@ paths:
type: string
description: attributeId
required: true
- name: dateStart
in: query
required: false
description: Parameter for data filtering. Updated date of returned data is greater than or equal to dateStart.
schema:
type: string
example: 2020-06-07
- name: dateEnd
in: query
required: false
description: Parameter for data filtering. Updated date of the returned data is less than or equal to dateEnd.
schema:
type: string
example: 2020-06-07
- name: lastDate
in: query
required: false
description: Parameter for data filtering. Return only items with last values.
schema:
type: boolean
example: true
- in: query
name: bottomLeft
schema:
Expand Down
4 changes: 2 additions & 2 deletions api/src/routes/pointAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ router.get(
'/',
swaggerValidation.validate,
forwardError(async (req, res) => {
const { bottomLeft, topRight, attributeId } = req.query;
const { bottomLeft, topRight, attributeId, dateStart, dateEnd, lastDate } = req.query;

const attributes = await getPointAttributes(attributeId, bottomLeft, topRight);
const attributes = await getPointAttributes(attributeId, bottomLeft, topRight, dateStart, dateEnd, lastDate);

if (attributes && attributes.length) {
res.send({
Expand Down

0 comments on commit fb1b403

Please sign in to comment.