From 7da7f58cbe174120021b1889efa555a83845b70d Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 7 Aug 2023 13:28:32 -0700 Subject: [PATCH] Added "columns" to query options. Added events count to event data metrics. --- .../pages/event-data/EventDataMetricsBar.js | 5 ++ lib/clickhouse.ts | 9 +-- lib/prisma.ts | 6 +- lib/types.ts | 12 ++-- pages/api/event-data/fields.ts | 6 +- pages/api/event-data/stats.ts | 4 +- .../analytics/eventData/getEventDataFields.ts | 68 +++++-------------- 7 files changed, 45 insertions(+), 65 deletions(-) diff --git a/components/pages/event-data/EventDataMetricsBar.js b/components/pages/event-data/EventDataMetricsBar.js index 48843287..90f065d5 100644 --- a/components/pages/event-data/EventDataMetricsBar.js +++ b/components/pages/event-data/EventDataMetricsBar.js @@ -28,6 +28,11 @@ export function EventDataMetricsBar({ websiteId }) { {!error && isFetched && ( <> + { const filter = filters[key]; - const column = FILTER_COLUMNS[key]; + const column = FILTER_COLUMNS[key] ?? options?.columns?.[key]; if (filter !== undefined && column) { arr.push(`and ${column} = {${key}:String}`); @@ -85,11 +85,12 @@ function getFilterQuery(filters = {}) { async function parseFilters( websiteId: string, filters: QueryFilters & { [key: string]: any } = {}, + options?: QueryOptions, ) { const website = await loadWebsite(websiteId); return { - filterQuery: getFilterQuery(filters), + filterQuery: getFilterQuery(filters, options), params: { ...filters, websiteId, diff --git a/lib/prisma.ts b/lib/prisma.ts index a9ddf188..753f1ae4 100644 --- a/lib/prisma.ts +++ b/lib/prisma.ts @@ -67,10 +67,10 @@ function getTimestampIntervalQuery(field: string): string { } } -function getFilterQuery(filters = {}): string { +function getFilterQuery(filters: QueryFilters = {}, options: QueryOptions = {}): string { const query = Object.keys(filters).reduce((arr, key) => { const filter = filters[key]; - const column = FILTER_COLUMNS[key]; + const column = FILTER_COLUMNS[key] ?? options?.columns?.[key]; if (filter !== undefined && column) { arr.push(`and ${column}={{${key}}}`); @@ -100,7 +100,7 @@ async function parseFilters( options?.joinSession || Object.keys(filters).find(key => SESSION_COLUMNS.includes(key)) ? `inner join session on website_event.session_id = session.session_id` : '', - filterQuery: getFilterQuery(filters), + filterQuery: getFilterQuery(filters, options), params: { ...filters, websiteId, diff --git a/lib/types.ts b/lib/types.ts index 6057c42e..dc54fd47 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -80,15 +80,15 @@ export interface WebsiteEventMetric { } export interface WebsiteEventDataStats { - field: string; - type: number; + fieldName: string; + dataType: number; total: number; } export interface WebsiteEventDataFields { - field: string; - type: number; - value?: string; + fieldName: string; + dataType: number; + fieldValue?: string; total: number; } @@ -152,5 +152,5 @@ export interface QueryFilters { export interface QueryOptions { joinSession?: boolean; - ignoreFilters?: string[]; + columns?: { [key: string]: string }; } diff --git a/pages/api/event-data/fields.ts b/pages/api/event-data/fields.ts index 18b74bc3..f21bd570 100644 --- a/pages/api/event-data/fields.ts +++ b/pages/api/event-data/fields.ts @@ -11,6 +11,7 @@ export interface EventDataFieldsRequestBody { startDate: string; endDate: string; }; + field?: string; } export default async ( @@ -27,7 +28,10 @@ export default async ( return unauthorized(res); } - const data = await getEventDataFields(websiteId, new Date(+startAt), new Date(+endAt), field); + const startDate = new Date(+startAt); + const endDate = new Date(+endAt); + + const data = await getEventDataFields(websiteId, { startDate, endDate, field }); return ok(res, data); } diff --git a/pages/api/event-data/stats.ts b/pages/api/event-data/stats.ts index 969568e2..74f420c4 100644 --- a/pages/api/event-data/stats.ts +++ b/pages/api/event-data/stats.ts @@ -32,16 +32,18 @@ export default async ( const endDate = new Date(+endAt); const results = await getEventDataFields(websiteId, { startDate, endDate }); + const events = new Set(); const data = results.reduce( (obj, row) => { + events.add(row.fieldName); obj.records += Number(row.total); return obj; }, { fields: results.length, records: 0 }, ); - return ok(res, data); + return ok(res, { ...data, events: events.size }); } return methodNotAllowed(res); diff --git a/queries/analytics/eventData/getEventDataFields.ts b/queries/analytics/eventData/getEventDataFields.ts index a27f2281..c61de517 100644 --- a/queries/analytics/eventData/getEventDataFields.ts +++ b/queries/analytics/eventData/getEventDataFields.ts @@ -14,39 +14,23 @@ export async function getEventDataFields( async function relationalQuery(websiteId: string, filters: QueryFilters & { field?: string }) { const { rawQuery, parseFilters } = prisma; - const { field } = filters; - const { params } = await parseFilters(websiteId, filters); - - if (field) { - return rawQuery( - ` - select - event_key as field, - string_value as value, - count(*) as total - from event_data - where website_id = {{websiteId::uuid}} - and event_key = {{field}} - and created_at between {{startDate}} and {{endDate}} - group by event_key, string_value - order by 3 desc, 2 desc, 1 asc - limit 100 - `, - params, - ); - } + const { filterQuery, params } = await parseFilters(websiteId, filters, { + columns: { field: 'event_key' }, + }); return rawQuery( ` select - event_key as field, - data_type as type, + event_key as fieldName, + data_type as dataType, + string_value as fieldValue, count(*) as total from event_data where website_id = {{websiteId::uuid}} and created_at between {{startDate}} and {{endDate}} - group by event_key, data_type - order by 3 desc, 2 asc, 1 asc + ${filterQuery} + group by event_key, data_type, string_value + order by 3 desc, 2 desc, 1 asc limit 100 `, params, @@ -55,39 +39,23 @@ async function relationalQuery(websiteId: string, filters: QueryFilters & { fiel async function clickhouseQuery(websiteId: string, filters: QueryFilters & { field?: string }) { const { rawQuery, parseFilters } = clickhouse; - const { field } = filters; - const { params } = await parseFilters(websiteId, filters); - - if (field) { - return rawQuery( - ` - select - event_key as field, - string_value as value, - count(*) as total - from event_data - where website_id = {websiteId:UUID} - and event_key = {field:String} - and created_at between {startDate:DateTime} and {endDate:DateTime} - group by event_key, string_value - order by 3 desc, 2 desc, 1 asc - limit 100 - `, - params, - ); - } + const { filterQuery, params } = await parseFilters(websiteId, filters, { + columns: { field: 'event_key' }, + }); return rawQuery( ` select - event_key as field, - data_type as type, + event_key as fieldName, + data_type as dataType, + string_value as fieldValue, count(*) as total from event_data where website_id = {websiteId:UUID} and created_at between {startDate:DateTime} and {endDate:DateTime} - group by event_key, data_type - order by 3 desc, 2 asc, 1 asc + ${filterQuery} + group by event_key, data_type, string_value + order by 3 desc, 2 desc, 1 asc limit 100 `, params,