From a18d1a923cc75c28eaaf597bce65f6be82f4224e Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Wed, 27 Nov 2024 23:43:28 -0800 Subject: [PATCH] Allow filter search for country and region. --- .../hooks/queries/useWebsiteValues.ts | 15 ++++--- src/lib/clickhouse.ts | 5 +++ src/lib/prisma.ts | 4 +- src/pages/api/websites/[websiteId]/values.ts | 8 +--- src/queries/analytics/getValues.ts | 40 ++++++++++++++++++- 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/components/hooks/queries/useWebsiteValues.ts b/src/components/hooks/queries/useWebsiteValues.ts index da0406ae..21985fdf 100644 --- a/src/components/hooks/queries/useWebsiteValues.ts +++ b/src/components/hooks/queries/useWebsiteValues.ts @@ -28,12 +28,15 @@ export function useWebsiteValues({ const getSearch = (type: string, value: string) => { if (value) { const values = names[type]; - return Object.keys(values).reduce((code: string, key: string) => { - if (!code && values[key].toLowerCase().includes(value.toLowerCase())) { - code = key; - } - return code; - }, ''); + return Object.keys(values) + .reduce((arr: string[], key: string) => { + if (values[key].toLowerCase().includes(value.toLowerCase())) { + return arr.concat(key); + } + return arr; + }, []) + .slice(0, 5) + .join(','); } }; diff --git a/src/lib/clickhouse.ts b/src/lib/clickhouse.ts index b588ec84..5f0248b4 100644 --- a/src/lib/clickhouse.ts +++ b/src/lib/clickhouse.ts @@ -68,6 +68,10 @@ function getDateSQL(field: string, unit: string, timezone?: string) { return `toDateTime(date_trunc('${unit}', ${field}))`; } +function getSearchSQL(column: string, param: string = 'search'): string { + return `and positionCaseInsensitive(${column}, {${param}:String}) > 0`; +} + function mapFilter(column: string, operator: string, name: string, type: string = 'String') { const value = `{${name}:${type}}`; @@ -229,6 +233,7 @@ export default { connect, getDateStringSQL, getDateSQL, + getSearchSQL, getFilterQuery, getUTCString, parseFilters, diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts index 4e3de37e..a8f7eb06 100644 --- a/src/lib/prisma.ts +++ b/src/lib/prisma.ts @@ -119,11 +119,11 @@ function getTimestampDiffSQL(field1: string, field2: string): string { } } -function getSearchSQL(column: string): string { +function getSearchSQL(column: string, param: string = 'search'): string { const db = getDatabaseType(); const like = db === POSTGRESQL ? 'ilike' : 'like'; - return `and ${column} ${like} {{search}}`; + return `and ${column} ${like} {{${param}}`; } function mapFilter(column: string, operator: string, name: string, type: string = '') { diff --git a/src/pages/api/websites/[websiteId]/values.ts b/src/pages/api/websites/[websiteId]/values.ts index 364261d9..53d717a5 100644 --- a/src/pages/api/websites/[websiteId]/values.ts +++ b/src/pages/api/websites/[websiteId]/values.ts @@ -49,13 +49,7 @@ export default async (req: NextApiRequestQueryBody, res: Nex return unauthorized(res); } - const values = await getValues( - websiteId, - FILTER_COLUMNS[type as string], - startDate, - endDate, - search, - ); + const values = await getValues(websiteId, FILTER_COLUMNS[type], startDate, endDate, search); return ok( res, diff --git a/src/queries/analytics/getValues.ts b/src/queries/analytics/getValues.ts index 8b1afb3f..f303faff 100644 --- a/src/queries/analytics/getValues.ts +++ b/src/queries/analytics/getValues.ts @@ -19,10 +19,25 @@ async function relationalQuery( search: string, ) { const { rawQuery, getSearchSQL } = prisma; + const params = {}; let searchQuery = ''; if (search) { - searchQuery = getSearchSQL(column); + if (decodeURIComponent(search).includes(',')) { + searchQuery = `AND (${decodeURIComponent(search) + .split(',') + .slice(0, 5) + .map((value: string, index: number) => { + const key = `search${index}`; + + params[key] = value; + + return getSearchSQL(column, key).replace('and ', ''); + }) + .join(' OR ')})`; + } else { + searchQuery = getSearchSQL(column); + } } return rawQuery( @@ -43,6 +58,7 @@ async function relationalQuery( startDate, endDate, search: `%${search}%`, + ...params, }, ); } @@ -54,13 +70,32 @@ async function clickhouseQuery( endDate: Date, search: string, ) { - const { rawQuery } = clickhouse; + const { rawQuery, getSearchSQL } = clickhouse; + const params = {}; let searchQuery = ''; if (search) { searchQuery = `and positionCaseInsensitive(${column}, {search:String}) > 0`; } + if (search) { + if (decodeURIComponent(search).includes(',')) { + searchQuery = `AND (${decodeURIComponent(search) + .split(',') + .slice(0, 5) + .map((value: string, index: number) => { + const key = `search${index}`; + + params[key] = value; + + return getSearchSQL(column, key).replace('and ', ''); + }) + .join(' OR ')})`; + } else { + searchQuery = getSearchSQL(column); + } + } + return rawQuery( ` select ${column} as value, count(*) @@ -77,6 +112,7 @@ async function clickhouseQuery( startDate, endDate, search, + ...params, }, ); }