1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
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
})
}
|