2021-06-15 15:46:49 +02:00
|
|
|
import { QueryResult } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
|
2020-10-13 17:05:57 +02:00
|
|
|
import { MetadataCache, Logger } from '@oceanprotocol/lib'
|
2021-01-21 10:42:05 +01:00
|
|
|
import queryString from 'query-string'
|
|
|
|
|
|
|
|
export const SortTermOptions = {
|
2021-06-15 15:46:49 +02:00
|
|
|
Created: 'created',
|
|
|
|
Relevance: '_score'
|
2021-01-21 10:42:05 +01:00
|
|
|
} 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]
|
|
|
|
|
2021-02-22 15:25:27 +01:00
|
|
|
export const FilterByTypeOptions = {
|
|
|
|
Data: 'dataset',
|
|
|
|
Algorithm: 'algorithm'
|
|
|
|
} as const
|
2021-05-20 00:44:51 +02:00
|
|
|
type FilterByTypeOptions =
|
|
|
|
typeof FilterByTypeOptions[keyof typeof FilterByTypeOptions]
|
2021-02-22 15:25:27 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2021-06-15 15:46:49 +02:00
|
|
|
function getSortType(sortParam: string): string {
|
|
|
|
const sortTerm =
|
|
|
|
sortParam === SortTermOptions.Created
|
|
|
|
? SortTermOptions.Created
|
|
|
|
: SortTermOptions.Relevance
|
2021-01-21 10:42:05 +01:00
|
|
|
return sortTerm
|
|
|
|
}
|
2020-05-07 08:03:30 +02:00
|
|
|
|
2020-06-30 15:24:30 +02:00
|
|
|
export function getSearchQuery(
|
2020-11-03 14:57:40 +01:00
|
|
|
text?: string,
|
|
|
|
owner?: string,
|
|
|
|
tags?: string,
|
|
|
|
categories?: string,
|
|
|
|
page?: string,
|
2021-01-21 10:42:05 +01:00
|
|
|
offset?: string,
|
|
|
|
sort?: string,
|
|
|
|
sortOrder?: string,
|
2021-02-22 15:25:27 +01:00
|
|
|
serviceType?: string
|
2021-06-15 15:46:49 +02:00
|
|
|
): any {
|
|
|
|
const sortTerm = getSortType(sort)
|
2021-01-21 10:42:05 +01:00
|
|
|
const sortValue = sortOrder === SortValueOptions.Ascending ? 1 : -1
|
2021-06-15 15:46:49 +02:00
|
|
|
const emptySearchTerm = text === undefined || text === ''
|
|
|
|
|
2021-01-21 10:42:05 +01:00
|
|
|
let searchTerm = owner
|
2020-11-14 15:02:54 +01:00
|
|
|
? `(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 || ''
|
2021-05-25 10:23:48 +02:00
|
|
|
|
2021-06-15 15:46:49 +02:00
|
|
|
searchTerm = searchTerm.trim()
|
|
|
|
let modifiedSearchTerm = searchTerm.split(' ').join(' OR ').trim()
|
|
|
|
modifiedSearchTerm = addTypeFilterToQuery(modifiedSearchTerm, serviceType)
|
2021-02-22 15:25:27 +01:00
|
|
|
searchTerm = addTypeFilterToQuery(searchTerm, serviceType)
|
2021-06-15 15:46:49 +02:00
|
|
|
const prefixedSearchTerm =
|
|
|
|
emptySearchTerm && searchTerm
|
|
|
|
? searchTerm
|
|
|
|
: !emptySearchTerm && searchTerm
|
|
|
|
? '*' + searchTerm + '*'
|
|
|
|
: '**'
|
2021-03-01 18:08:18 +01:00
|
|
|
|
2020-06-30 15:24:30 +02:00
|
|
|
return {
|
|
|
|
page: Number(page) || 1,
|
2020-10-28 12:33:53 +01:00
|
|
|
offset: Number(offset) || 21,
|
2020-06-30 15:24:30 +02:00
|
|
|
query: {
|
2021-06-15 15:46:49 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
2020-11-14 15:02:54 +01:00
|
|
|
}
|
2020-06-30 15:24:30 +02:00
|
|
|
},
|
|
|
|
sort: {
|
2021-01-21 10:42:05 +01:00
|
|
|
[sortTerm]: sortValue
|
2020-06-30 15:24:30 +02:00
|
|
|
}
|
2021-03-18 12:27:58 +01:00
|
|
|
}
|
2020-06-30 15:24:30 +02:00
|
|
|
}
|
|
|
|
|
2020-08-11 15:56:13 +02:00
|
|
|
export async function getResults(
|
2020-10-24 17:39:51 +02:00
|
|
|
params: {
|
|
|
|
text?: string
|
2020-11-03 14:57:40 +01:00
|
|
|
owner?: string
|
2020-10-24 17:39:51 +02:00
|
|
|
tags?: string
|
|
|
|
categories?: string
|
|
|
|
page?: string
|
|
|
|
offset?: string
|
2021-01-21 10:42:05 +01:00
|
|
|
sort?: string
|
|
|
|
sortOrder?: string
|
2021-02-22 15:25:27 +01:00
|
|
|
serviceType?: string
|
2020-10-24 17:39:51 +02:00
|
|
|
},
|
2020-10-13 17:05:57 +02:00
|
|
|
metadataCacheUri: string
|
2020-08-11 15:56:13 +02:00
|
|
|
): Promise<QueryResult> {
|
2021-01-21 10:42:05 +01:00
|
|
|
const {
|
|
|
|
text,
|
|
|
|
owner,
|
|
|
|
tags,
|
2021-06-15 15:46:49 +02:00
|
|
|
categories,
|
2021-01-21 10:42:05 +01:00
|
|
|
page,
|
|
|
|
offset,
|
|
|
|
sort,
|
|
|
|
sortOrder,
|
2021-02-22 15:25:27 +01:00
|
|
|
serviceType
|
2021-01-21 10:42:05 +01:00
|
|
|
} = params
|
2020-10-13 17:05:57 +02:00
|
|
|
const metadataCache = new MetadataCache(metadataCacheUri, Logger)
|
2021-05-17 15:14:40 +02:00
|
|
|
|
2020-11-05 14:43:13 +01:00
|
|
|
const searchQuery = getSearchQuery(
|
|
|
|
text,
|
|
|
|
owner,
|
|
|
|
tags,
|
|
|
|
categories,
|
|
|
|
page,
|
2021-01-21 10:42:05 +01:00
|
|
|
offset,
|
|
|
|
sort,
|
|
|
|
sortOrder,
|
2021-02-22 15:25:27 +01:00
|
|
|
serviceType
|
2020-05-07 08:03:30 +02:00
|
|
|
)
|
2021-05-17 15:14:40 +02:00
|
|
|
const queryResult = await metadataCache.queryMetadata(searchQuery)
|
2020-06-30 15:24:30 +02:00
|
|
|
return queryResult
|
2020-05-07 08:03:30 +02:00
|
|
|
}
|
2021-01-21 10:42:05 +01:00
|
|
|
|
|
|
|
export async function addExistingParamsToUrl(
|
|
|
|
location: Location,
|
2021-06-15 15:46:49 +02:00
|
|
|
excludedParams: string[]
|
2021-01-21 10:42:05 +01:00
|
|
|
): Promise<string> {
|
|
|
|
const parsed = queryString.parse(location.search)
|
|
|
|
let urlLocation = '/search?'
|
|
|
|
if (Object.keys(parsed).length > 0) {
|
|
|
|
for (const querryParam in parsed) {
|
2021-06-15 15:46:49 +02:00
|
|
|
if (!excludedParams.includes(querryParam)) {
|
|
|
|
if (querryParam === 'page' && excludedParams.includes('text')) {
|
2021-01-21 10:42:05 +01:00
|
|
|
Logger.log('remove page when starting a new search')
|
|
|
|
} else {
|
|
|
|
const value = parsed[querryParam]
|
|
|
|
urlLocation = `${urlLocation}${querryParam}=${value}&`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2021-06-15 15:46:49 +02:00
|
|
|
// sort should be relevance when fixed in aqua
|
|
|
|
urlLocation = `${urlLocation}sort=${encodeURIComponent(
|
|
|
|
SortTermOptions.Created
|
|
|
|
)}&sortOrder=${SortValueOptions.Descending}&`
|
2021-01-21 10:42:05 +01:00
|
|
|
}
|
|
|
|
urlLocation = urlLocation.slice(0, -1)
|
|
|
|
return urlLocation
|
|
|
|
}
|