Merge 334297f194
into 586529a5ca
commit
f361dc5f53
|
@ -6,6 +6,7 @@ import classNames from 'classnames';
|
||||||
import useApi from 'hooks/useApi';
|
import useApi from 'hooks/useApi';
|
||||||
import { percentFilter } from 'lib/filters';
|
import { percentFilter } from 'lib/filters';
|
||||||
import useDateRange from 'hooks/useDateRange';
|
import useDateRange from 'hooks/useDateRange';
|
||||||
|
import useTimezone from 'hooks/useTimezone';
|
||||||
import usePageQuery from 'hooks/usePageQuery';
|
import usePageQuery from 'hooks/usePageQuery';
|
||||||
import ErrorMessage from 'components/common/ErrorMessage';
|
import ErrorMessage from 'components/common/ErrorMessage';
|
||||||
import DataTable from './DataTable';
|
import DataTable from './DataTable';
|
||||||
|
@ -26,7 +27,8 @@ export function MetricsTable({
|
||||||
delay = null,
|
delay = null,
|
||||||
...props
|
...props
|
||||||
}) {
|
}) {
|
||||||
const [{ startDate, endDate, modified }] = useDateRange(websiteId);
|
const [{ startDate, endDate, modified, unit }] = useDateRange(websiteId);
|
||||||
|
const [timezone] = useTimezone();
|
||||||
const {
|
const {
|
||||||
resolveUrl,
|
resolveUrl,
|
||||||
router,
|
router,
|
||||||
|
@ -53,6 +55,9 @@ export function MetricsTable({
|
||||||
country,
|
country,
|
||||||
region,
|
region,
|
||||||
city,
|
city,
|
||||||
|
unit,
|
||||||
|
timezone,
|
||||||
|
includeEventData: type === 'event',
|
||||||
}),
|
}),
|
||||||
{ onSuccess: onDataLoad, retryDelay: delay || DEFAULT_ANIMATION_DURATION },
|
{ onSuccess: onDataLoad, retryDelay: delay || DEFAULT_ANIMATION_DURATION },
|
||||||
);
|
);
|
||||||
|
@ -69,7 +74,7 @@ export function MetricsTable({
|
||||||
return items.sort(firstBy('y', -1).thenBy('x'));
|
return items.sort(firstBy('y', -1).thenBy('x'));
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}, [data, error, dataFilter, filterOptions]);
|
}, [data, dataFilter, filterOptions, limit]);
|
||||||
const { dir } = useLocale();
|
const { dir } = useLocale();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -104,6 +104,7 @@ CREATE TABLE umami.event_data
|
||||||
event_string_value Nullable(String),
|
event_string_value Nullable(String),
|
||||||
event_numeric_value Nullable(Decimal64(4)), --922337203685477.5625
|
event_numeric_value Nullable(Decimal64(4)), --922337203685477.5625
|
||||||
event_date_value Nullable(DateTime('UTC')),
|
event_date_value Nullable(DateTime('UTC')),
|
||||||
|
event_bool_value Nullable(Boolean),
|
||||||
event_data_type UInt32,
|
event_data_type UInt32,
|
||||||
created_at DateTime('UTC')
|
created_at DateTime('UTC')
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `event_data` ADD COLUMN `event_bool_value` BOOLEAN NULL;
|
|
@ -14,7 +14,7 @@ model User {
|
||||||
password String @db.VarChar(60)
|
password String @db.VarChar(60)
|
||||||
role String @map("role") @db.VarChar(50)
|
role String @map("role") @db.VarChar(50)
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||||
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
||||||
|
|
||||||
website Website[]
|
website Website[]
|
||||||
|
@ -53,7 +53,7 @@ model Website {
|
||||||
resetAt DateTime? @map("reset_at") @db.Timestamp(0)
|
resetAt DateTime? @map("reset_at") @db.Timestamp(0)
|
||||||
userId String? @map("user_id") @db.VarChar(36)
|
userId String? @map("user_id") @db.VarChar(36)
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||||
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
||||||
|
|
||||||
user User? @relation(fields: [userId], references: [id])
|
user User? @relation(fields: [userId], references: [id])
|
||||||
|
@ -99,6 +99,7 @@ model EventData {
|
||||||
eventStringValue String? @map("event_string_value") @db.VarChar(500)
|
eventStringValue String? @map("event_string_value") @db.VarChar(500)
|
||||||
eventNumericValue Decimal? @map("event_numeric_value") @db.Decimal(19, 4)
|
eventNumericValue Decimal? @map("event_numeric_value") @db.Decimal(19, 4)
|
||||||
eventDateValue DateTime? @map("event_date_value") @db.Timestamp(0)
|
eventDateValue DateTime? @map("event_date_value") @db.Timestamp(0)
|
||||||
|
eventBoolValue Boolean? @map("event_bool_value")
|
||||||
eventDataType Int @map("event_data_type") @db.UnsignedInt
|
eventDataType Int @map("event_data_type") @db.UnsignedInt
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||||
|
|
||||||
|
@ -117,7 +118,7 @@ model Team {
|
||||||
name String @db.VarChar(50)
|
name String @db.VarChar(50)
|
||||||
accessCode String? @unique @map("access_code") @db.VarChar(50)
|
accessCode String? @unique @map("access_code") @db.VarChar(50)
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||||
|
|
||||||
teamUser TeamUser[]
|
teamUser TeamUser[]
|
||||||
teamWebsite TeamWebsite[]
|
teamWebsite TeamWebsite[]
|
||||||
|
@ -132,7 +133,7 @@ model TeamUser {
|
||||||
userId String @map("user_id") @db.VarChar(36)
|
userId String @map("user_id") @db.VarChar(36)
|
||||||
role String @map("role") @db.VarChar(50)
|
role String @map("role") @db.VarChar(50)
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||||
|
|
||||||
team Team @relation(fields: [teamId], references: [id])
|
team Team @relation(fields: [teamId], references: [id])
|
||||||
user User @relation(fields: [userId], references: [id])
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "event_data" ADD COLUMN "event_bool_value" BOOLEAN;
|
|
@ -14,7 +14,7 @@ model User {
|
||||||
password String @db.VarChar(60)
|
password String @db.VarChar(60)
|
||||||
role String @map("role") @db.VarChar(50)
|
role String @map("role") @db.VarChar(50)
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||||
|
|
||||||
website Website[]
|
website Website[]
|
||||||
|
@ -53,7 +53,7 @@ model Website {
|
||||||
resetAt DateTime? @map("reset_at") @db.Timestamptz(6)
|
resetAt DateTime? @map("reset_at") @db.Timestamptz(6)
|
||||||
userId String? @map("user_id") @db.Uuid
|
userId String? @map("user_id") @db.Uuid
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||||
|
|
||||||
user User? @relation(fields: [userId], references: [id])
|
user User? @relation(fields: [userId], references: [id])
|
||||||
|
@ -99,6 +99,7 @@ model EventData {
|
||||||
eventStringValue String? @map("event_string_value") @db.VarChar(500)
|
eventStringValue String? @map("event_string_value") @db.VarChar(500)
|
||||||
eventNumericValue Decimal? @map("event_numeric_value") @db.Decimal(19, 4)
|
eventNumericValue Decimal? @map("event_numeric_value") @db.Decimal(19, 4)
|
||||||
eventDateValue DateTime? @map("event_date_value") @db.Timestamptz(6)
|
eventDateValue DateTime? @map("event_date_value") @db.Timestamptz(6)
|
||||||
|
eventBoolValue Boolean? @map("event_bool_value") @db.Boolean
|
||||||
eventDataType Int @map("event_data_type") @db.Integer
|
eventDataType Int @map("event_data_type") @db.Integer
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ model Team {
|
||||||
name String @db.VarChar(50)
|
name String @db.VarChar(50)
|
||||||
accessCode String? @unique @map("access_code") @db.VarChar(50)
|
accessCode String? @unique @map("access_code") @db.VarChar(50)
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||||
|
|
||||||
teamUser TeamUser[]
|
teamUser TeamUser[]
|
||||||
teamWebsite TeamWebsite[]
|
teamWebsite TeamWebsite[]
|
||||||
|
@ -131,7 +132,7 @@ model TeamUser {
|
||||||
userId String @map("user_id") @db.Uuid
|
userId String @map("user_id") @db.Uuid
|
||||||
role String @map("role") @db.VarChar(50)
|
role String @map("role") @db.VarChar(50)
|
||||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||||
updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6)
|
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||||
|
|
||||||
team Team @relation(fields: [teamId], references: [id])
|
team Team @relation(fields: [teamId], references: [id])
|
||||||
user User @relation(fields: [userId], references: [id])
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
|
|
@ -69,6 +69,7 @@ export interface WebsiteActive {
|
||||||
export interface WebsiteMetric {
|
export interface WebsiteMetric {
|
||||||
x: string;
|
x: string;
|
||||||
y: number;
|
y: number;
|
||||||
|
d?: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WebsiteMetricFilter {
|
export interface WebsiteMetricFilter {
|
||||||
|
@ -90,6 +91,7 @@ export interface WebsiteEventMetric {
|
||||||
x: string;
|
x: string;
|
||||||
t: string;
|
t: string;
|
||||||
y: number;
|
y: number;
|
||||||
|
d?: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WebsiteEventDataMetric {
|
export interface WebsiteEventDataMetric {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
|
import { methodNotAllowed, ok, unauthorized, badRequest } from 'next-basics';
|
||||||
import { WebsiteMetric, NextApiRequestQueryBody } from 'lib/types';
|
import { WebsiteMetric, NextApiRequestQueryBody } from 'lib/types';
|
||||||
import { canViewWebsite } from 'lib/auth';
|
import { canViewWebsite } from 'lib/auth';
|
||||||
import { useAuth, useCors } from 'lib/middleware';
|
import { useAuth, useCors } from 'lib/middleware';
|
||||||
import { SESSION_COLUMNS, EVENT_COLUMNS, FILTER_COLUMNS } from 'lib/constants';
|
import { SESSION_COLUMNS, EVENT_COLUMNS, FILTER_COLUMNS } from 'lib/constants';
|
||||||
import { getPageviewMetrics, getSessionMetrics } from 'queries';
|
import { getEventMetrics, getPageviewMetrics, getSessionMetrics } from 'queries';
|
||||||
|
import moment from 'moment-timezone';
|
||||||
|
const unitTypes = ['year', 'month', 'hour', 'day'];
|
||||||
|
|
||||||
export interface WebsiteMetricsRequestQuery {
|
export interface WebsiteMetricsRequestQuery {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -47,6 +49,9 @@ export default async (
|
||||||
country,
|
country,
|
||||||
region,
|
region,
|
||||||
city,
|
city,
|
||||||
|
includeEventData,
|
||||||
|
timezone,
|
||||||
|
unit,
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
|
@ -54,6 +59,15 @@ export default async (
|
||||||
return unauthorized(res);
|
return unauthorized(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof timezone !== 'string' ||
|
||||||
|
typeof unit !== 'string' ||
|
||||||
|
!moment.tz.zone(String(timezone)) ||
|
||||||
|
!unitTypes.includes(String(unit))
|
||||||
|
) {
|
||||||
|
return badRequest(res);
|
||||||
|
}
|
||||||
|
|
||||||
const startDate = new Date(+startAt);
|
const startDate = new Date(+startAt);
|
||||||
const endDate = new Date(+endAt);
|
const endDate = new Date(+endAt);
|
||||||
|
|
||||||
|
@ -114,6 +128,17 @@ export default async (
|
||||||
|
|
||||||
filters[type] = undefined;
|
filters[type] = undefined;
|
||||||
|
|
||||||
|
if (type === 'event' && includeEventData) {
|
||||||
|
const data = await getEventMetrics(websiteId, {
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
timezone,
|
||||||
|
unit,
|
||||||
|
filters: { url: filters.url, eventName: undefined },
|
||||||
|
});
|
||||||
|
|
||||||
|
return ok(res, data);
|
||||||
|
}
|
||||||
const data = await getPageviewMetrics(websiteId, {
|
const data = await getPageviewMetrics(websiteId, {
|
||||||
startDate,
|
startDate,
|
||||||
endDate,
|
endDate,
|
||||||
|
|
|
@ -52,18 +52,38 @@ async function relationalQuery(
|
||||||
const filterQuery = getFilterQuery(filters, params);
|
const filterQuery = getFilterQuery(filters, params);
|
||||||
|
|
||||||
return rawQuery(
|
return rawQuery(
|
||||||
`select
|
`with event_data as (
|
||||||
event_name x,
|
select d.website_event_id,
|
||||||
${getDateQuery('created_at', unit, timezone)} t,
|
jsonb_object_agg(
|
||||||
|
d.event_key,
|
||||||
|
case
|
||||||
|
d.event_data_type
|
||||||
|
when 1 then to_jsonb(d.event_string_value) -- string
|
||||||
|
when 2 then to_jsonb(d.event_numeric_value) -- number
|
||||||
|
when 3 then to_jsonb(d.event_bool_value) -- boolean
|
||||||
|
when 4 then to_jsonb(d.event_date_value) -- date
|
||||||
|
when 5 then d.event_string_value::jsonb -- array
|
||||||
|
end
|
||||||
|
) filter (
|
||||||
|
where d.event_key is not null
|
||||||
|
) as event_data
|
||||||
|
from event_data d
|
||||||
|
group by d.website_event_id
|
||||||
|
)
|
||||||
|
select
|
||||||
|
w.event_name x,
|
||||||
|
d.event_data d,
|
||||||
|
${getDateQuery('w.created_at', unit, timezone)} t,
|
||||||
count(*) y
|
count(*) y
|
||||||
from website_event
|
from website_event w
|
||||||
|
left join event_data d on w.event_id = d.website_event_id
|
||||||
where website_id = $1${toUuid()}
|
where website_id = $1${toUuid()}
|
||||||
and created_at >= $2
|
and created_at >= $2
|
||||||
and created_at between $3 and $4
|
and created_at between $3 and $4
|
||||||
and event_type = ${EVENT_TYPE.customEvent}
|
and event_type = ${EVENT_TYPE.customEvent}
|
||||||
${filterQuery}
|
${filterQuery}
|
||||||
group by 1, 2
|
group by 1, 2, 3
|
||||||
order by 2`,
|
order by 3`,
|
||||||
params,
|
params,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -93,17 +113,37 @@ async function clickhouseQuery(
|
||||||
const params = { websiteId };
|
const params = { websiteId };
|
||||||
|
|
||||||
return rawQuery(
|
return rawQuery(
|
||||||
`select
|
`with event_data as (
|
||||||
event_name x,
|
select d.website_event_id,
|
||||||
${getDateQuery('created_at', unit, timezone)} t,
|
jsonb_object_agg(
|
||||||
|
d.event_key,
|
||||||
|
case
|
||||||
|
d.event_data_type
|
||||||
|
when 1 then to_jsonb(d.event_string_value) -- string
|
||||||
|
when 2 then to_jsonb(d.event_numeric_value) -- number
|
||||||
|
when 3 then to_jsonb(d.event_bool_value) -- boolean
|
||||||
|
when 4 then to_jsonb(d.event_date_value) -- date
|
||||||
|
when 5 then d.event_string_value::jsonb -- array
|
||||||
|
end
|
||||||
|
) filter (
|
||||||
|
where d.event_key is not null
|
||||||
|
) as event_data
|
||||||
|
from event_data d
|
||||||
|
group by d.website_event_id
|
||||||
|
)
|
||||||
|
select
|
||||||
|
w.event_name x,
|
||||||
|
d.event_data d,
|
||||||
|
${getDateQuery('w.created_at', unit, timezone)} t,
|
||||||
count(*) y
|
count(*) y
|
||||||
from website_event
|
from website_event w
|
||||||
|
left join event_data d on w.event_id = d.website_event_id
|
||||||
where website_id = {websiteId:UUID}
|
where website_id = {websiteId:UUID}
|
||||||
and event_type = ${EVENT_TYPE.customEvent}
|
and w.event_type = ${EVENT_TYPE.customEvent}
|
||||||
and created_at >= ${getDateFormat(resetDate)}
|
and w.created_at >= ${getDateFormat(resetDate)}
|
||||||
and ${getBetweenDates('created_at', startDate, endDate)}
|
and ${getBetweenDates('w.created_at', startDate, endDate)}
|
||||||
${getFilterQuery(filters, params)}
|
${getFilterQuery(filters, params)}
|
||||||
group by x, t
|
group by x, d, t
|
||||||
order by t`,
|
order by t`,
|
||||||
params,
|
params,
|
||||||
);
|
);
|
||||||
|
|
|
@ -38,13 +38,12 @@ async function relationalQuery(data: {
|
||||||
websiteId,
|
websiteId,
|
||||||
eventKey: a.key,
|
eventKey: a.key,
|
||||||
eventStringValue:
|
eventStringValue:
|
||||||
a.eventDataType === EVENT_DATA_TYPE.string ||
|
a.eventDataType === EVENT_DATA_TYPE.string || a.eventDataType === EVENT_DATA_TYPE.array
|
||||||
a.eventDataType === EVENT_DATA_TYPE.boolean ||
|
|
||||||
a.eventDataType === EVENT_DATA_TYPE.array
|
|
||||||
? a.value
|
? a.value
|
||||||
: null,
|
: null,
|
||||||
eventNumericValue: a.eventDataType === EVENT_DATA_TYPE.number ? a.value : null,
|
eventNumericValue: a.eventDataType === EVENT_DATA_TYPE.number ? a.value : null,
|
||||||
eventDateValue: a.eventDataType === EVENT_DATA_TYPE.date ? new Date(a.value) : null,
|
eventDateValue: a.eventDataType === EVENT_DATA_TYPE.date ? new Date(a.value) : null,
|
||||||
|
eventBoolValue: a.eventDataType === EVENT_DATA_TYPE.boolean ? a.value : null,
|
||||||
eventDataType: a.eventDataType,
|
eventDataType: a.eventDataType,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -76,13 +75,12 @@ async function clickhouseQuery(data: {
|
||||||
event_name: eventName,
|
event_name: eventName,
|
||||||
event_key: a.key,
|
event_key: a.key,
|
||||||
event_string_value:
|
event_string_value:
|
||||||
a.eventDataType === EVENT_DATA_TYPE.string ||
|
a.eventDataType === EVENT_DATA_TYPE.string || a.eventDataType === EVENT_DATA_TYPE.array
|
||||||
a.eventDataType === EVENT_DATA_TYPE.boolean ||
|
|
||||||
a.eventDataType === EVENT_DATA_TYPE.array
|
|
||||||
? a.value
|
? a.value
|
||||||
: null,
|
: null,
|
||||||
event_numeric_value: a.eventDataType === EVENT_DATA_TYPE.number ? a.value : null,
|
event_numeric_value: a.eventDataType === EVENT_DATA_TYPE.number ? a.value : null,
|
||||||
event_date_value: a.eventDataType === EVENT_DATA_TYPE.date ? getDateFormat(a.value) : null,
|
event_date_value: a.eventDataType === EVENT_DATA_TYPE.date ? getDateFormat(a.value) : null,
|
||||||
|
event_bool_value: a.eventDataType === EVENT_DATA_TYPE.boolean ? a.value : null,
|
||||||
event_data_type: a.eventDataType,
|
event_data_type: a.eventDataType,
|
||||||
created_at: createdAt,
|
created_at: createdAt,
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -102,7 +102,7 @@ async function clickhouseQuery(
|
||||||
where website_id = {websiteId:UUID}
|
where website_id = {websiteId:UUID}
|
||||||
and event_type = {eventType:UInt32}
|
and event_type = {eventType:UInt32}
|
||||||
and created_at >= ${getDateFormat(resetDate)}
|
and created_at >= ${getDateFormat(resetDate)}
|
||||||
and ${getBetweenDates('created_at', startDate, endDate)}
|
and ${getBetweenDates('created_at', startDate, endDate)}
|
||||||
${excludeDomain}
|
${excludeDomain}
|
||||||
${filterQuery}
|
${filterQuery}
|
||||||
group by x
|
group by x
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
select *
|
||||||
|
from event_data -- WHERE event_data.website_event_id = '91bac2f4-4039-4b2a-a2ab-8c86f71ef95d'
|
|
@ -0,0 +1,30 @@
|
||||||
|
WITH event_data_query AS (
|
||||||
|
SELECT d.website_event_id,
|
||||||
|
jsonb_object_agg(
|
||||||
|
d.event_key,
|
||||||
|
CASE
|
||||||
|
d.event_data_type
|
||||||
|
when 1 then to_jsonb(d.event_string_value) -- string
|
||||||
|
when 2 then to_jsonb(d.event_numeric_value) -- number
|
||||||
|
when 3 then to_jsonb(d.event_bool_value) -- boolean
|
||||||
|
when 4 then to_jsonb(d.event_date_value) -- date
|
||||||
|
when 5 then d.event_string_value::jsonb -- array
|
||||||
|
end
|
||||||
|
) filter (
|
||||||
|
where d.event_key is not null
|
||||||
|
) as event_data
|
||||||
|
FROM event_data d
|
||||||
|
GROUP BY d.website_event_id
|
||||||
|
)
|
||||||
|
select e.event_name x,
|
||||||
|
to_char(
|
||||||
|
date_trunc('hour', e.created_at),
|
||||||
|
'YYYY-MM-DD HH24:00:00'
|
||||||
|
) c,
|
||||||
|
edq.event_data::jsonb->'data.target' t,
|
||||||
|
edq.event_data::jsonb->'data.release' r
|
||||||
|
from website_event e
|
||||||
|
LEFT JOIN event_data_query edq ON e.event_id = edq.website_event_id
|
||||||
|
where e.event_name = 'Outbound click'
|
||||||
|
or e.event_name = 'NewSong PRO click'
|
||||||
|
order by c desc
|
Loading…
Reference in New Issue