Skip to content
This repository was archived by the owner on May 28, 2023. It is now read-only.

Commit f6c61f9

Browse files
author
tkostuch
committed
3948 add transformAggsToAttributeListParam, and support graphql
1 parent fc57251 commit f6c61f9

File tree

4 files changed

+44
-34
lines changed

4 files changed

+44
-34
lines changed

src/api/attribute/service.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,33 @@ export interface AttributeListParam {
99
[key: string]: number[]
1010
}
1111

12+
/**
13+
* Transforms ES aggregates into valid format for AttributeService - {[attribute_code]: [bucketId1, bucketId2]}
14+
* @param body - products response body
15+
* @param config - global config
16+
* @param indexName - current indexName
17+
*/
18+
function transformAggsToAttributeListParam (aggregations): AttributeListParam {
19+
const attributeListParam: AttributeListParam = Object.keys(aggregations)
20+
.filter(key => aggregations[key].buckets.length) // leave only buckets with values
21+
.reduce((acc, key) => {
22+
const attributeCode = key.replace(/^(agg_terms_|agg_range_)|(_options)$/g, '')
23+
const bucketsIds = aggregations[key].buckets.map(bucket => bucket.key)
24+
25+
if (!acc[attributeCode]) {
26+
acc[attributeCode] = []
27+
}
28+
29+
// there can be more then one attributes for example 'agg_terms_color' and 'agg_terms_color_options'
30+
// we need to get buckets from both
31+
acc[attributeCode] = [...new Set([...acc[attributeCode], ...bucketsIds])]
32+
33+
return acc
34+
}, {})
35+
36+
return attributeListParam
37+
}
38+
1239
/**
1340
* Returns attributes from cache
1441
*/
@@ -149,5 +176,6 @@ function transformToMetadata ({
149176

150177
export default {
151178
list,
152-
transformToMetadata
179+
transformToMetadata,
180+
transformAggsToAttributeListParam
153181
}

src/api/catalog.ts

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import ProcessorFactory from '../processor/factory';
44
import { adjustBackendProxyUrl } from '../lib/elastic'
55
import cache from '../lib/cache-instance'
66
import { sha3_224 } from 'js-sha3'
7-
import AttributeService, { AttributeListParam } from './attribute/service'
7+
import AttributeService from './attribute/service'
88
import bodybuilder from 'bodybuilder'
99
import { elasticsearch, SearchQuery } from 'storefront-query-builder'
1010

@@ -20,36 +20,6 @@ function _cacheStorageHandler (config, result, hash, tags) {
2020
}
2121
}
2222

23-
/**
24-
* Transforms ES aggregates into valid format for AttributeService - {[attribute_code]: [bucketId1, bucketId2]}
25-
* @param body - products response body
26-
* @param config - global config
27-
* @param indexName - current indexName
28-
*/
29-
async function getProductsAttributesMetadata (body, config, indexName: string): Promise<any> {
30-
const attributeListParam: AttributeListParam = Object.keys(body.aggregations)
31-
.filter(key => body.aggregations[key].buckets.length) // leave only buckets with values
32-
.reduce((acc, key) => {
33-
const attributeCode = key.replace(/^(agg_terms_|agg_range_)|(_options)$/g, '')
34-
const bucketsIds = body.aggregations[key].buckets.map(bucket => bucket.key)
35-
36-
if (!acc[attributeCode]) {
37-
acc[attributeCode] = []
38-
}
39-
40-
// there can be more then one attributes for example 'agg_terms_color' and 'agg_terms_color_options'
41-
// we need to get buckets from both
42-
acc[attributeCode] = [...new Set([...acc[attributeCode], ...bucketsIds])]
43-
44-
return acc
45-
}, {})
46-
47-
// find attribute list
48-
const attributeList: any[] = await AttributeService.list(attributeListParam, config, indexName)
49-
50-
return attributeList
51-
}
52-
5323
function _outputFormatter (responseBody, format = 'standard') {
5424
if (format === 'compact') { // simple formatter
5525
delete responseBody.took
@@ -161,8 +131,10 @@ export default ({config, db}) => async function (req, res, body) {
161131
_resBody.hits.hits = result
162132
_cacheStorageHandler(config, _resBody, reqHash, tagsArray)
163133
if (_resBody.aggregations) {
164-
const attributesMetadata = await getProductsAttributesMetadata(_resBody, config, indexName)
165-
_resBody.attribute_metadata = attributesMetadata.map(AttributeService.transformToMetadata)
134+
const attributeListParam = AttributeService.transformAggsToAttributeListParam(_resBody.aggregations)
135+
// find attribute list
136+
const attributeList = await AttributeService.list(attributeListParam, config, indexName)
137+
_resBody.attribute_metadata = attributeList.map(AttributeService.transformToMetadata)
166138
}
167139
res.json(_outputFormatter(_resBody, responseFormat));
168140
}).catch((err) => {

src/graphql/elasticsearch/catalog/resolver.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { buildQuery } from '../queryBuilder';
44
import esResultsProcessor from './processor'
55
import { getIndexName } from '../mapping'
66
import { adjustQuery } from './../../../lib/elastic'
7+
import AttributeService from './../../../api/attribute/service'
78

89
const resolver = {
910
Query: {
@@ -67,6 +68,13 @@ async function list (filter, sort, currentPage, pageSize, search, context, rootV
6768
}
6869

6970
response.aggregations = esResponse.aggregations
71+
72+
if (response.aggregations) {
73+
const attributeListParam = AttributeService.transformAggsToAttributeListParam(response.aggregations)
74+
const attributeList = await AttributeService.list(attributeListParam, config, esIndex)
75+
response.attribute_metadata = attributeList.map(AttributeService.transformToMetadata)
76+
}
77+
7078
response.sort_fields = {}
7179
if (sortOptions.length > 0) {
7280
response.sort_fields.options = sortOptions

src/graphql/elasticsearch/catalog/schema.graphqls

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ type Products @doc(description: "The Products object is the top-level object ret
77
total_count: Int @doc(description: "The number of products returned")
88
# filters: [LayerFilter] @doc(description: "Layered navigation filters array") // @TODO: add filters to response instead of aggregations
99
aggregations: JSON @doc(description: "Layered navigation filters array as aggregations")
10+
attribute_metadata: JSON @doc(description: "Transformed aggregations into attributes")
1011
sort_fields: SortFields @doc(description: "An object that includes the default sort field and all available sort fields")
1112
}
1213

1314
type ESResponse {
1415
hits: JSON
1516
suggest: JSON
1617
aggregations: JSON
18+
attribute_metadata: JSON
1719
}
1820

1921
type Query {

0 commit comments

Comments
 (0)