Merge branch 'feature/tags-backend' into 'develop'

implemented tags endpoint

See merge request tjohn/cc-data!26
This commit is contained in:
Timo Volkmann 2020-06-24 10:46:09 +02:00
commit 2fb2e9a76f
3 changed files with 43 additions and 25 deletions

13
backend/models/getTags.js Normal file
View File

@ -0,0 +1,13 @@
exports.getUniqueTags = async (dbConn) => {
let tags = await dbConn.query(
`SELECT DISTINCT name FROM region_feedback;`
);
return tags;
};
exports.allTagsWithValues = async (dbConn) => {
let tags = await dbConn.query(
`SELECT * FROM region_feedback;`
);
return tags;
};

View File

@ -4,16 +4,29 @@ const getSearchPresets = require("../models/getSearchPresets.js");
const base64 = require("../util/base64.js") const base64 = require("../util/base64.js")
const sas = require("../util/scoreAndSearch.js"); const sas = require("../util/scoreAndSearch.js");
const oldToNewQuerySyntax = require("../util/oldToNewQuerySyntax.js") const oldToNewQuerySyntax = require("../util/oldToNewQuerySyntax.js")
const getRegions = require('../models/getRegions.js') const getRegions = require('../models/getRegions.js');
const { allTagsWithValues, getUniqueTags } = require("../models/getTags.js");
const { getClimateMinMax } = require("../util/getClimateMinMax.js");
module.exports = dbConn => { module.exports = dbConn => {
router.get("/api/v1/search", searchHandler(dbConn)); router.get("/api/v1/search", searchHandler(dbConn));
router.get("/api/v1/search/presets", presetHandler(dbConn)); router.get("/api/v1/search/presets", presetHandler(dbConn));
router.get("/api/v1/search/tags", tagsHandler(dbConn));
return router; return router;
}; };
function tagsHandler(dbConn) {
return function (req, res) {
getUniqueTags(dbConn).then(tags => {
res.json(tags.map(tag => tag.name))
}).catch(error => {
// TODO error handling
})
}
}
function presetHandler(dbConn) { function presetHandler(dbConn) {
return function (req, res) { return function (req, res) {
getSearchPresets(dbConn).then(presets => { getSearchPresets(dbConn).then(presets => {
@ -46,18 +59,20 @@ function searchHandler(dbConn) {
// CHOOSE PARAMS WHICH SHALL BE PASSED TO SCORE AND SEARCH // CHOOSE PARAMS WHICH SHALL BE PASSED TO SCORE AND SEARCH
let scoreQueryObj = prepareQueries(q) let scoreQueryObj = prepareQueries(q)
let data = await getRegions(dbConn) let [regions, tags, boundaryClimate] = await Promise.all([getRegions(dbConn), allTagsWithValues(dbConn), getClimateMinMax(dbConn)])
let data = {
regions: regions,
tags: tags,
boundaryClimate: boundaryClimate
}
// FILTER if query contains filterString // FILTER if query contains filterString
if (q.textfilter) { if (q.textfilter) {
data = filterByString(data, q.textfilter, q.fulltext) data.regions = filterByString(data.regions, q.textfilter, q.fulltext)
} }
scoreAndSearch(data, q.from, q.to, scoreQueryObj).then(searchResults => { scoreAndSearch(data, q.from, q.to, scoreQueryObj).then(searchResults => {
//response.data = searchResults
const cutScores = !(_.isEmpty(scoreQueryObj.climate) && _.isEmpty(scoreQueryObj.costs) && _.isEmpty(scoreQueryObj.others))
// only dev: // only dev:
if (process.env.SHOW_MATCH_VALUE === '1') searchResults.forEach(reg => reg.name = `${reg.name} (${_.round(reg.score * 10, 1)}% match)`) if (process.env.SHOW_MATCH_VALUE === '1') searchResults.forEach(reg => reg.name = `${reg.name} (${_.round(reg.score * 10, 1)}% match)`)

View File

@ -23,22 +23,21 @@ const SETTINGS = {
} }
module.exports = function (dbConn) { module.exports = function (dbConn) {
return async function (regions, from, to, q) { return async function (data, from, to, q) {
console.log('search') console.log('search')
if ((_.isNil(to) || _.isNil(from)) && !(_.isEmpty(q.climate) || _.isEmpty(q.costs) || _.isEmpty(q.others))) { if ((_.isNil(to) || _.isNil(from)) && !(_.isEmpty(q.climate) || _.isEmpty(q.costs) || _.isEmpty(q.others))) {
throw new Error('invalid query') throw new Error('invalid query')
} }
if (_.isNil(data) || _.isEmpty(data.regions) || _.isEmpty(data.tags) || _.isEmpty(data.boundaryClimate)) {
throw new Error('database error')
}
let regionsArr = data.regions
// PREPARE SEARCH // PREPARE SEARCH
// validate dates // validate dates
const dates = validateDates(from, to) const dates = validateDates(from, to)
// for calculating average if traveldates are in more than one month // for calculating average if traveldates are in more than one month
const travelPeriods = travelPeriodsFromDates(dates) const travelPeriods = travelPeriodsFromDates(dates)
// FETCH DATA FROM DB
const boundaryClimate = await getClimateMinMax.getClimateMinMax(dbConn)
// let regions = await getRegions(dbConn)
regions.forEach(reg => reg.scores = [])
const boundaryStatic = { const boundaryStatic = {
max: { max: {
accommodation_costs: 500, accommodation_costs: 500,
@ -63,21 +62,12 @@ module.exports = function (dbConn) {
} }
} }
// little tweak to show score object without request DEPRECATED
if (SHOW_ALL_SCOREOBJECTS) {
if (!q.climate.temperature_mean_max) q.climate.temperature_mean_max = [null, null]
if (!q.climate.precipitation) q.climate.precipitation = [null, null]
if (!q.climate.rain_days) q.climate.rain_days = [null, null]
if (!q.climate.sun_hours) q.climate.sun_hours = [null, null]
if (!q.climate.accommodation_costs) q.climate.accommodation_costs = [null, null]
}
// CALCULATE PROPERTIES FOR EACH REGION // CALCULATE PROPERTIES FOR EACH REGION
regions.forEach(reg => { regionsArr.forEach(reg => {
reg.scores = []
// CALCULATE SCORES FOR CLIMATE PROPS // CALCULATE SCORES FOR CLIMATE PROPS
Object.entries(q.climate).forEach(([key, value]) => { Object.entries(q.climate).forEach(([key, value]) => {
let finalScoreObj = calculateScoreForPeriod(key, travelPeriods, reg, value[0], value[1], boundaryClimate) let finalScoreObj = calculateScoreForPeriod(key, travelPeriods, reg, value[0], value[1], data.boundaryClimate)
reg.scores.push(finalScoreObj) reg.scores.push(finalScoreObj)
}); });
@ -116,7 +106,7 @@ module.exports = function (dbConn) {
reg.score = calculateAverage(reg.scores) reg.score = calculateAverage(reg.scores)
// reg.score = _.sum(scoreSubGroups) / scoreSubGroups.length // reg.score = _.sum(scoreSubGroups) / scoreSubGroups.length
}) })
return _.orderBy(regions, ({ score }) => score || 0, 'desc') //.filter(el => !_.isNaN(el.score)) return _.orderBy(regionsArr, ({ score }) => score || 0, 'desc') //.filter(el => !_.isNaN(el.score))
} }
function sumForRangeAvg(from, to, avg) { function sumForRangeAvg(from, to, avg) {