First tries to search local elastic instance, if no results are found a reject is thrown and we search vinmonopolet api manually.
98 lines
2.1 KiB
JavaScript
98 lines
2.1 KiB
JavaScript
const fetch = require("node-fetch");
|
|
|
|
const ELASTIC_URL = 'http://localhost:9200';
|
|
const INDEX_URL = `${ELASTIC_URL}/wines*`;
|
|
|
|
const verifyAndUnpackElasticSearchResult = response => {
|
|
const searchHits = response?.hits?.hits;
|
|
|
|
if (searchHits == null || searchHits.length == 0) {
|
|
return Promise.reject({
|
|
statusCode: 404,
|
|
message: `Nothing found in vinmonopolet cache matching this.`,
|
|
})
|
|
}
|
|
|
|
return searchHits;
|
|
}
|
|
|
|
const getWineObjectFromSearchHit = hit => {
|
|
const { wine } = hit?._source;
|
|
|
|
if (wine == null) {
|
|
return Promise.reject({
|
|
statusCode: 500,
|
|
message: `Found response, but it's missing a wine object. Unable to convert!`,
|
|
})
|
|
}
|
|
|
|
return wine;
|
|
}
|
|
|
|
const wineById = id => {
|
|
const url = `${INDEX_URL}/_search`
|
|
const options = {
|
|
method: 'POST',
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
"size": 1,
|
|
"query": {
|
|
"match": {
|
|
"wine.code": id
|
|
}
|
|
},
|
|
"_source": {
|
|
"includes": "wine"
|
|
},
|
|
"sort": [
|
|
{
|
|
"@timestamp": "desc"
|
|
}
|
|
]
|
|
})
|
|
}
|
|
|
|
return fetch(url, options)
|
|
.then(resp => resp.json())
|
|
.then(verifyAndUnpackElasticSearchResult)
|
|
.then(searchHits => getWineObjectFromSearchHit(searchHits[0]))
|
|
}
|
|
|
|
const wineByQueryName = (name, page=1, size=25) => {
|
|
const url = `${INDEX_URL}/_search`
|
|
const options = {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json', },
|
|
body: JSON.stringify({
|
|
"from": page - 1,
|
|
"size": size,
|
|
"query": {
|
|
"multi_match" : {
|
|
"query" : name,
|
|
"fields": ["wine.name"],
|
|
"fuzziness": 2
|
|
}
|
|
},
|
|
"sort": [
|
|
{
|
|
"_score": {
|
|
"order": "desc"
|
|
}
|
|
}
|
|
],
|
|
"_source": {
|
|
"includes": "wine"
|
|
}
|
|
})
|
|
};
|
|
|
|
return fetch(url, options)
|
|
.then(resp => resp.json())
|
|
.then(verifyAndUnpackElasticSearchResult)
|
|
.then(searchHits => Promise.all(searchHits.map(getWineObjectFromSearchHit)))
|
|
}
|
|
|
|
module.exports = {
|
|
wineById,
|
|
wineByQueryName
|
|
} |