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
 | 
						|
} |