diff --git a/backend/models/getTags.js b/backend/models/getTags.js new file mode 100644 index 0000000..8dda86e --- /dev/null +++ b/backend/models/getTags.js @@ -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; +}; \ No newline at end of file diff --git a/backend/routes/search.js b/backend/routes/search.js index 2045db8..d8c3aa4 100644 --- a/backend/routes/search.js +++ b/backend/routes/search.js @@ -4,16 +4,29 @@ const getSearchPresets = require("../models/getSearchPresets.js"); const base64 = require("../util/base64.js") const sas = require("../util/scoreAndSearch.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 => { router.get("/api/v1/search", searchHandler(dbConn)); router.get("/api/v1/search/presets", presetHandler(dbConn)); + router.get("/api/v1/search/tags", tagsHandler(dbConn)); 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) { return function (req, res) { getSearchPresets(dbConn).then(presets => { @@ -46,18 +59,20 @@ function searchHandler(dbConn) { // CHOOSE PARAMS WHICH SHALL BE PASSED TO SCORE AND SEARCH 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 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 => { - //response.data = searchResults - const cutScores = !(_.isEmpty(scoreQueryObj.climate) && _.isEmpty(scoreQueryObj.costs) && _.isEmpty(scoreQueryObj.others)) - // only dev: if (process.env.SHOW_MATCH_VALUE === '1') searchResults.forEach(reg => reg.name = `${reg.name} (${_.round(reg.score * 10, 1)}% match)`) diff --git a/backend/util/scoreAndSearch.js b/backend/util/scoreAndSearch.js index 6657941..2bc3399 100644 --- a/backend/util/scoreAndSearch.js +++ b/backend/util/scoreAndSearch.js @@ -23,22 +23,21 @@ const SETTINGS = { } module.exports = function (dbConn) { - return async function (regions, from, to, q) { + return async function (data, from, to, q) { console.log('search') if ((_.isNil(to) || _.isNil(from)) && !(_.isEmpty(q.climate) || _.isEmpty(q.costs) || _.isEmpty(q.others))) { 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 // validate dates const dates = validateDates(from, to) // for calculating average if traveldates are in more than one month 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 = { max: { 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 - regions.forEach(reg => { - + regionsArr.forEach(reg => { + reg.scores = [] // CALCULATE SCORES FOR CLIMATE PROPS 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) }); @@ -116,7 +106,7 @@ module.exports = function (dbConn) { reg.score = calculateAverage(reg.scores) // 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) {