1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-06-16 17:33:26 +02:00
market/src/components/templates/Search/utils.ts
claudiaHash eb8c6afb62
Search issues fix (#641)
* search by addresses

* search by asset id

* logs deleted

* search query updated

* search query updated

* search terms differentiated

* asset id hack

* id search hack removed

* restore lock file

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* remove SearchQuery return type

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* refine query, add relevance sort

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* remove old comments

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* remove white spaces from search term endings

* fix filter by type

* wip on filter with empty search text

* sort by relevance fix

* linting errors fix

* lint fixes

* comment sort by relevance

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* lint

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* search by owner and tags fix

* lint  err fix

* fix search

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

Co-authored-by: claudia.holhos <claudia.holhos@hpm.ro>
Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro>
2021-06-15 16:46:49 +03:00

222 lines
6.1 KiB
TypeScript

import { QueryResult } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
import { MetadataCache, Logger } from '@oceanprotocol/lib'
import queryString from 'query-string'
export const SortTermOptions = {
Created: 'created',
Relevance: '_score'
} as const
type SortTermOptions = typeof SortTermOptions[keyof typeof SortTermOptions]
export const SortElasticTerm = {
Liquidity: 'price.ocean',
Price: 'price.value',
Created: 'created'
} as const
type SortElasticTerm = typeof SortElasticTerm[keyof typeof SortElasticTerm]
export const SortValueOptions = {
Ascending: 'asc',
Descending: 'desc'
} as const
type SortValueOptions = typeof SortValueOptions[keyof typeof SortValueOptions]
export const FilterByTypeOptions = {
Data: 'dataset',
Algorithm: 'algorithm'
} as const
type FilterByTypeOptions =
typeof FilterByTypeOptions[keyof typeof FilterByTypeOptions]
function addTypeFilterToQuery(sortTerm: string, typeFilter: string): string {
sortTerm = typeFilter
? sortTerm === ''
? `service.attributes.main.type:${typeFilter}`
: `${sortTerm} AND service.attributes.main.type:${typeFilter}`
: sortTerm
return sortTerm
}
function getSortType(sortParam: string): string {
const sortTerm =
sortParam === SortTermOptions.Created
? SortTermOptions.Created
: SortTermOptions.Relevance
return sortTerm
}
export function getSearchQuery(
text?: string,
owner?: string,
tags?: string,
categories?: string,
page?: string,
offset?: string,
sort?: string,
sortOrder?: string,
serviceType?: string
): any {
const sortTerm = getSortType(sort)
const sortValue = sortOrder === SortValueOptions.Ascending ? 1 : -1
const emptySearchTerm = text === undefined || text === ''
let searchTerm = owner
? `(publicKey.owner:${owner})`
: tags
? // eslint-disable-next-line no-useless-escape
`(service.attributes.additionalInformation.tags:\"${tags}\")`
: categories
? // eslint-disable-next-line no-useless-escape
`(service.attributes.additionalInformation.categories:\"${categories}\")`
: text || ''
searchTerm = searchTerm.trim()
let modifiedSearchTerm = searchTerm.split(' ').join(' OR ').trim()
modifiedSearchTerm = addTypeFilterToQuery(modifiedSearchTerm, serviceType)
searchTerm = addTypeFilterToQuery(searchTerm, serviceType)
const prefixedSearchTerm =
emptySearchTerm && searchTerm
? searchTerm
: !emptySearchTerm && searchTerm
? '*' + searchTerm + '*'
: '**'
return {
page: Number(page) || 1,
offset: Number(offset) || 21,
query: {
bool: {
must: [
{
bool: {
should: [
{
query_string: {
query: `${modifiedSearchTerm}`,
fields: [
'id',
'publicKey.owner',
'dataToken',
'dataTokenInfo.name',
'dataTokenInfo.symbol',
'service.attributes.main.name^10',
'service.attributes.main.author',
'service.attributes.additionalInformation.description',
'service.attributes.additionalInformation.tags'
],
minimum_should_match: '2<75%',
phrase_slop: 2,
boost: 5
}
},
{
match_phrase: {
content: {
query: `${searchTerm}`,
boost: 10
}
}
},
{
query_string: {
query: `${prefixedSearchTerm}`,
fields: [
'id',
'publicKey.owner',
'dataToken',
'dataTokenInfo.name',
'dataTokenInfo.symbol',
'service.attributes.main.name',
'service.attributes.main.author',
'service.attributes.additionalInformation.description',
'service.attributes.additionalInformation.tags'
],
default_operator: 'AND'
}
}
]
}
},
{
term: {
isInPurgatory: false
}
}
]
}
},
sort: {
[sortTerm]: sortValue
}
}
}
export async function getResults(
params: {
text?: string
owner?: string
tags?: string
categories?: string
page?: string
offset?: string
sort?: string
sortOrder?: string
serviceType?: string
},
metadataCacheUri: string
): Promise<QueryResult> {
const {
text,
owner,
tags,
categories,
page,
offset,
sort,
sortOrder,
serviceType
} = params
const metadataCache = new MetadataCache(metadataCacheUri, Logger)
const searchQuery = getSearchQuery(
text,
owner,
tags,
categories,
page,
offset,
sort,
sortOrder,
serviceType
)
const queryResult = await metadataCache.queryMetadata(searchQuery)
return queryResult
}
export async function addExistingParamsToUrl(
location: Location,
excludedParams: string[]
): Promise<string> {
const parsed = queryString.parse(location.search)
let urlLocation = '/search?'
if (Object.keys(parsed).length > 0) {
for (const querryParam in parsed) {
if (!excludedParams.includes(querryParam)) {
if (querryParam === 'page' && excludedParams.includes('text')) {
Logger.log('remove page when starting a new search')
} else {
const value = parsed[querryParam]
urlLocation = `${urlLocation}${querryParam}=${value}&`
}
}
}
} else {
// sort should be relevance when fixed in aqua
urlLocation = `${urlLocation}sort=${encodeURIComponent(
SortTermOptions.Created
)}&sortOrder=${SortValueOptions.Descending}&`
}
urlLocation = urlLocation.slice(0, -1)
return urlLocation
}