Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fuzzy and operator usage when handling IS requests #2568

Merged
merged 8 commits into from
Nov 21, 2024
22 changes: 11 additions & 11 deletions packages/api/mocks/AllProductsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,16 @@ export const AllProductsQueryFirst5 = `query AllProducts {
`

export const productSearchPage1Count5Fetch = {
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=1&count=5&query=&sort=&fuzzy=auto&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=1&count=5&query=&sort=&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
init: undefined,
options: { storeCookies: expect.any(Function) },
result: {
products: [
{
cacheId: 'sp-99995946',
productId: '99995946',
description: '4k Philips Monitor 27\"',
productName: '4k Philips Monitor 27\"',
description: '4k Philips Monitor 27"',
productName: '4k Philips Monitor 27"',
linkText: '4k-philips-monitor',
brand: 'adidas',
brandId: 2000004,
Expand Down Expand Up @@ -209,7 +209,7 @@ export const productSearchPage1Count5Fetch = {
],
itemId: '99988213',
name: 'Monitor 27',
nameComplete: '4k Philips Monitor 27\" Monitor 27',
nameComplete: '4k Philips Monitor 27" Monitor 27',
complementName: '',
referenceId: [
{
Expand Down Expand Up @@ -831,36 +831,36 @@ export const productSearchPage1Count5Fetch = {
current: {
index: 1,
proxyUrl:
'search/trade-policy/1?page=1&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=1&count=5&query=&sort=&fuzzy=0&operator=and',
},
before: [],
after: [
{
index: 2,
proxyUrl:
'search/trade-policy/1?page=2&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=2&count=5&query=&sort=&fuzzy=0&operator=and',
},
{
index: 3,
proxyUrl:
'search/trade-policy/1?page=3&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=3&count=5&query=&sort=&fuzzy=0&operator=and',
},
{
index: 4,
proxyUrl:
'search/trade-policy/1?page=4&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=4&count=5&query=&sort=&fuzzy=0&operator=and',
},
{
index: 5,
proxyUrl:
'search/trade-policy/1?page=5&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=5&count=5&query=&sort=&fuzzy=0&operator=and',
},
],
perPage: 5,
next: {
index: 2,
proxyUrl:
'search/trade-policy/1?page=2&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=2&count=5&query=&sort=&fuzzy=0&operator=and',
},
previous: {
index: 0,
Expand All @@ -871,7 +871,7 @@ export const productSearchPage1Count5Fetch = {
last: {
index: 50,
proxyUrl:
'search/trade-policy/1?page=50&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=50&count=5&query=&sort=&fuzzy=0&operator=and',
},
},
},
Expand Down
6 changes: 3 additions & 3 deletions packages/api/mocks/ProductQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const ProductByIdQuery = `query ProductQuery {
`

export const productSearchFetch = {
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=1&count=1&query=sku%3A64953394&sort=&fuzzy=auto&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=1&count=1&query=sku%3A64953394&sort=&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
init: undefined,
options: { storeCookies: expect.any(Function) },
result: {
Expand Down Expand Up @@ -229,15 +229,15 @@ export const productSearchFetch = {
correction: {
misspelled: true,
},
fuzzy: 'auto',
fuzzy: '0',
operator: 'and',
translated: false,
pagination: {
count: 1,
current: {
index: 1,
proxyUrl:
'search/trade-policy/1?page=1&count=1&query=sku:64953394&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=1&count=1&query=sku:64953394&sort=&locale=en-US&hide-unavailable-items=false&operator=and&fuzzy=0',
},
before: [],
after: [],
Expand Down
2 changes: 1 addition & 1 deletion packages/api/mocks/RedirectQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const RedirectQueryTermTech = `query RedirectSearch {
`

export const redirectTermTechFetch = {
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=2&count=1&query=tech&sort=&fuzzy=auto&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=2&count=1&query=tech&sort=&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
init: undefined,
options: { storeCookies: expect.any(Function) },
result: {
Expand Down
18 changes: 9 additions & 9 deletions packages/api/mocks/SearchQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const SearchQueryFirst5Products = `query SearchQuery {
}`

export const productSearchCategory1Fetch = {
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/category-1/office/trade-policy/1?page=1&count=5&query=&sort=&fuzzy=auto&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/category-1/office/trade-policy/1?page=1&count=5&query=&sort=&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
init: undefined,
options: { storeCookies: expect.any(Function) },
result: {
Expand Down Expand Up @@ -1348,36 +1348,36 @@ export const productSearchCategory1Fetch = {
current: {
index: 1,
proxyUrl:
'search/category-1/office/trade-policy/1?page=1&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/category-1/office/trade-policy/1?page=1&count=5&query=&sort=&operator=and&fuzzy=0',
},
before: [],
after: [
{
index: 2,
proxyUrl:
'search/category-1/office/trade-policy/1?page=2&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/category-1/office/trade-policy/1?page=2&count=5&query=&sort=&operator=and&fuzzy=0',
},
{
index: 3,
proxyUrl:
'search/category-1/office/trade-policy/1?page=3&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/category-1/office/trade-policy/1?page=3&count=5&query=&sort=&operator=and&fuzzy=0',
},
{
index: 4,
proxyUrl:
'search/category-1/office/trade-policy/1?page=4&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/category-1/office/trade-policy/1?page=4&count=5&query=&sort=&operator=and&fuzzy=0',
},
{
index: 5,
proxyUrl:
'search/category-1/office/trade-policy/1?page=5&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/category-1/office/trade-policy/1?page=5&count=5&query=&sort=&operator=and&fuzzy=0',
},
],
perPage: 5,
next: {
index: 2,
proxyUrl:
'search/category-1/office/trade-policy/1?page=2&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/category-1/office/trade-policy/1?page=2&count=5&query=&sort=&operator=and&fuzzy=0',
},
previous: {
index: 0,
Expand All @@ -1388,14 +1388,14 @@ export const productSearchCategory1Fetch = {
last: {
index: 50,
proxyUrl:
'search/category-1/office/trade-policy/1?page=50&count=5&query=&sort=&fuzzy=auto&operator=and',
'search/category-1/office/trade-policy/1?page=50&count=5&query=&sort=&operator=and&fuzzy=0',
},
},
},
}

export const attributeSearchCategory1Fetch = {
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/facets/category-1/office/trade-policy/1?page=1&count=5&query=&sort=&fuzzy=auto&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/facets/category-1/office/trade-policy/1?page=1&count=5&query=&sort=&locale=en-US&hideUnavailableItems=false&simulationBehavior=skip&showSponsored=false',
init: undefined,
options: { storeCookies: expect.any(Function) },
result: {
Expand Down
4 changes: 2 additions & 2 deletions packages/api/mocks/ValidateCartMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ export const checkoutOrderFormCustomDataInvalidFetch = {
}

export const productSearchPage1Count1Fetch = {
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=1&count=1&query=sku%3A2737806&sort=&fuzzy=auto&locale=en-US&show-invisible-items=true&hideUnavailableItems=false',
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=1&count=1&query=sku%3A2737806&sort=&locale=en-US&show-invisible-items=true&hideUnavailableItems=false',
init: undefined,
options: { storeCookies: expect.any(Function) },
result: {
Expand Down Expand Up @@ -523,7 +523,7 @@ export const productSearchPage1Count1Fetch = {
current: {
index: 1,
proxyUrl:
'search/trade-policy/1?page=1&count=1&query=sku:2737806&sort=&fuzzy=auto&operator=and',
'search/trade-policy/1?page=1&count=1&query=sku:2737806&sort=&locale=en-US&hide-unavailable-items=false&operator=and&fuzzy=0',
},
before: [],
after: [],
Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/__generated__/schema.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 44 additions & 5 deletions packages/api/src/platforms/vtex/clients/search/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Context, Options } from '../../'
import type { IStoreSelectedFacet } from '../../../../__generated__/schema'
import { getStoreCookie } from '../../utils/cookies'
import type { SelectedFacet } from '../../utils/facets'
import type { FuzzyFacet, OperatorFacet, SelectedFacet } from '../../utils/facets'
import { fetchAPI } from '../fetch'
import type {
Facet,
Expand Down Expand Up @@ -43,12 +43,33 @@ export interface ProductLocator {

const POLICY_KEY = 'trade-policy'
const REGION_KEY = 'region-id'
const CHANNEL_KEYS = new Set([POLICY_KEY, REGION_KEY])
const FUZZY_KEY = 'fuzzy'
const OPERATOR_KEY = 'operator'

const EXTRA_FACETS_KEYS = new Set([
POLICY_KEY,
REGION_KEY,
FUZZY_KEY,
OPERATOR_KEY,
])

export const isFacetBoolean = (
facet: Facet
): facet is Facet<FacetValueBoolean> => facet.type === 'TEXT'

const isFuzzyFacet = (facet: SelectedFacet): facet is FuzzyFacet => {
return (
facet.key === 'fuzzy' &&
(facet.value === '0' || facet.value === '1' || facet.value === 'auto')
)
}

const isOperatorFacet = (facet: SelectedFacet): facet is OperatorFacet => {
return (
facet.key === 'operator' && (facet.value === 'and' || facet.value === 'or')
)
}

export const IntelligentSearch = (
{ account, environment, hideUnavailableItems, simulationBehavior, showSponsored }: Options,
ctx: Context
Expand Down Expand Up @@ -87,7 +108,9 @@ export const IntelligentSearch = (
}

const addDefaultFacets = (facets: SelectedFacet[]) => {
const withDefaultFacets = facets.filter(({ key }) => !CHANNEL_KEYS.has(key))
const withDefaultFacets = facets.filter(
({ key }) => !EXTRA_FACETS_KEYS.has(key)
)

const policyFacet =
facets.find(({ key }) => key === POLICY_KEY) ?? getPolicyFacet()
Expand All @@ -106,25 +129,41 @@ export const IntelligentSearch = (
return withDefaultFacets
}

const addSearchParamsFacets = (
facets: SelectedFacet[],
params: URLSearchParams
) => {
const fuzzyFacet = facets.find(({ key }) => key === FUZZY_KEY) ?? null
const operatorFacet = facets.find(({ key }) => key === OPERATOR_KEY) ?? null

if (fuzzyFacet && isFuzzyFacet(fuzzyFacet)) {
params.append(FUZZY_KEY, fuzzyFacet.value)
}

if (operatorFacet && isOperatorFacet(operatorFacet)) {
params.append(OPERATOR_KEY, operatorFacet.value)
}
}

const search = <T>({
query = '',
page,
count,
sort = '',
selectedFacets = [],
type,
fuzzy = 'auto',
showInvisibleItems,
}: SearchArgs): Promise<T> => {
const params = new URLSearchParams({
page: (page + 1).toString(),
count: count.toString(),
query,
sort,
fuzzy,
locale: ctx.storage.locale,
})

addSearchParamsFacets(selectedFacets, params)

if (showInvisibleItems) {
params.append('show-invisible-items', 'true')
}
Expand Down
7 changes: 2 additions & 5 deletions packages/api/src/platforms/vtex/resolvers/searchResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,13 @@ export const StoreSearchResult: Record<string, Resolver<Root>> = {

return filteredFacets
},
metadata: async ({ searchArgs, productSearchPromise }) => {
if (!searchArgs.query) {
return null
}
lariciamota marked this conversation as resolved.
Show resolved Hide resolved

metadata: async ({ productSearchPromise }) => {
const productSearchResult = await productSearchPromise

return {
isTermMisspelled: productSearchResult.correction?.misspelled ?? false,
logicalOperator: productSearchResult.operator,
fuzzy: productSearchResult.fuzzy
}
},
}
10 changes: 10 additions & 0 deletions packages/api/src/platforms/vtex/utils/facets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ export const FACET_CROSS_SELLING_MAP = {
suggestions: "suggestions",
} as const

export type FuzzyFacet = {
key: 'fuzzy'
value: '0' | '1' | 'auto'
}

export type OperatorFacet = {
key: 'operator'
value: 'and' | 'or'
}

/**
* Transform facets from the store to VTEX platform facets.
* For instance, the channel in Store becomes trade-policy and regionId in VTEX's realm
Expand Down
4 changes: 4 additions & 0 deletions packages/api/src/typeDefs/query.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ type SearchMetadata {
Logical operator used to run the search.
"""
logicalOperator: String!
"""
Indicates how the search engine corrected the misspelled word by using fuzzy logic.
"""
fuzzy: String
}

"""
Expand Down
4 changes: 2 additions & 2 deletions packages/core/@generated/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const documents = {
types.SubscribeToNewsletterDocument,
'\n query ClientManyProductsQuery(\n $first: Int!\n $after: String\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientManyProducts\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n ...ProductSummary_product\n }\n }\n }\n }\n }\n':
types.ClientManyProductsQueryDocument,
'\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n }\n':
'\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n fuzzy\n }\n':
types.ClientProductGalleryQueryDocument,
'\n query ClientProductQuery($locator: [IStoreSelectedFacet!]!) {\n ...ClientProduct\n product(locator: $locator) {\n ...ProductDetailsFragment_product\n }\n }\n':
types.ClientProductQueryDocument,
Expand Down Expand Up @@ -158,7 +158,7 @@ export function gql(
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function gql(
source: '\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n }\n'
source: '\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n fuzzy\n }\n'
): typeof import('./graphql').ClientProductGalleryQueryDocument
/**
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
Expand Down
Loading
Loading