import axios from 'axios' import camelcaseObjectDeep from 'camelcase-object-deep' export default async function handler(req, res) { const { q = '*', page = 1, brand = '', category = '', priceFrom = 0, priceTo = 0, orderBy = '', operation = 'AND', fq = '', limit = 30 } = req.query let paramOrderBy = 'product_rating_f DESC' switch (orderBy) { case 'price-asc': paramOrderBy += ', price_discount_f ASC' break case 'price-desc': paramOrderBy += ', price_discount_f DESC' break case 'popular': paramOrderBy += ', search_rank_i DESC' break case 'stock': paramOrderBy += ', stock_total_f DESC' break } let offset = (page - 1) * limit let parameter = [ 'facet.field=manufacture_name', 'facet.field=category_name', 'facet=true', 'indent=true', `facet.query=${escapeSolrQuery(q)}`, `q.op=${operation}`, `q=${escapeSolrQuery(q)}`, 'qf=name_s', `start=${offset}`, `rows=${limit}`, `sort=${paramOrderBy}`, `fq=price_discount_f:[${priceFrom == '' ? '*' : priceFrom} TO ${priceTo == '' ? '*' : priceTo}]` ] if (brand) parameter.push(`fq=manufacture_name:${brand}`) if (category) parameter.push(`fq=category_name:${category}`) // Single fq in url params if (typeof fq === 'string') parameter.push(`fq=${fq}`) // Multi fq in url params if (Array.isArray(fq)) parameter = parameter.concat(fq.map((val) => `fq=${val}`)) let result = await axios(process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&')) try { result.data.response.products = productResponseMap(result.data.response.docs) result.data.responseHeader.params.start = parseInt(result.data.responseHeader.params.start) result.data.responseHeader.params.rows = parseInt(result.data.responseHeader.params.rows) delete result.data.response.docs result.data = camelcaseObjectDeep(result.data) res.status(200).json(result.data) } catch (error) { res.status(400).json({ error: error.message }) } } const escapeSolrQuery = (query) => { if (query == '*') return query const specialChars = /([\+\-\!\(\)\{\}\[\]\^"~\*\?:\\\/])/g const words = query.split(/\s+/) const escapedWords = words.map((word) => { if (specialChars.test(word)) { return `"${word.replace(specialChars, '\\$1')}"` } return word }) return escapedWords.join(' ') } const productResponseMap = (products) => { return products.map((product) => { let productMapped = { id: product.product_id_i || '', image: product.image_s || '', code: product.default_code_s || '', name: product.name_s || '', lowestPrice: { price: product.price_f || 0, priceDiscount: product.price_discount_f || 0, discountPercentage: product.discount_f || 0 }, variantTotal: product.variant_total_i || 0, stockTotal: product.stock_total_f || 0, weight: product.weight_f || 0, manufacture: {}, categories: [] } if (product.manufacture_id_i && product.manufacture_name_s) { productMapped.manufacture = { id: product.manufacture_id_i || '', name: product.manufacture_name_s || '' } } productMapped.categories = [ { id: product.category_id_i || '', name: product.category_name_s || '' } ] return productMapped }) }