update api to new CH columns

This commit is contained in:
Francis Cao 2022-10-08 16:12:33 -07:00
parent 36edbe2f4c
commit 96add409b6
19 changed files with 74 additions and 48 deletions

View File

@ -3,9 +3,9 @@ SET allow_experimental_object_type = 1;
-- Create Event -- Create Event
CREATE TABLE event CREATE TABLE event
( (
website_id UInt32, website_id UUID,
session_uuid UUID, session_id UUID,
event_uuid Nullable(UUID), event_id Nullable(UUID),
--session --session
hostname LowCardinality(String), hostname LowCardinality(String),
browser LowCardinality(String), browser LowCardinality(String),
@ -27,9 +27,9 @@ CREATE TABLE event
SETTINGS index_granularity = 8192; SETTINGS index_granularity = 8192;
CREATE TABLE event_queue ( CREATE TABLE event_queue (
website_id UInt32, website_id UUID,
session_uuid UUID, session_id UUID,
event_uuid Nullable(UUID), event_id Nullable(UUID),
url String, url String,
referrer String, referrer String,
hostname LowCardinality(String), hostname LowCardinality(String),
@ -52,9 +52,9 @@ SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input bro
kafka_skip_broken_messages = 1; kafka_skip_broken_messages = 1;
CREATE MATERIALIZED VIEW event_queue_mv TO event AS CREATE MATERIALIZED VIEW event_queue_mv TO event AS
SELECT website_id, SELECT website_id UUID,
session_uuid, session_id UUID,
event_uuid, event_id,
url, url,
referrer, referrer,
hostname, hostname,

View File

@ -60,6 +60,10 @@ function getDateFormat(date) {
return `'${dateFormat(date, 'UTC:yyyy-mm-dd HH:MM:ss')}'`; return `'${dateFormat(date, 'UTC:yyyy-mm-dd HH:MM:ss')}'`;
} }
function getCommaSeparatedStringFormat(data, column) {
return data.map(obj => `'${obj[column]}'`).join(',');
}
function getBetweenDates(field, start_at, end_at) { function getBetweenDates(field, start_at, end_at) {
return `${field} between ${getDateFormat(start_at)} return `${field} between ${getDateFormat(start_at)}
and ${getDateFormat(end_at)}`; and ${getDateFormat(end_at)}`;
@ -180,6 +184,7 @@ export default {
getDateStringQuery, getDateStringQuery,
getDateQuery, getDateQuery,
getDateFormat, getDateFormat,
getCommaSeparatedStringFormat,
getBetweenDates, getBetweenDates,
getFilterQuery, getFilterQuery,
parseFilters, parseFilters,

View File

@ -66,7 +66,7 @@ export async function getSession(req) {
if (!sessionId) { if (!sessionId) {
try { try {
session = await createSession(websiteId, { session = await createSession(websiteId, website_uuid, {
session_uuid, session_uuid,
hostname, hostname,
browser, browser,
@ -98,6 +98,7 @@ export async function getSession(req) {
return { return {
website_id: websiteId, website_id: websiteId,
website_uuid: website_uuid,
session, session,
}; };
} }

View File

@ -59,7 +59,7 @@ export default async (req, res) => {
await useSession(req, res); await useSession(req, res);
const { const {
session: { website_id, session }, session: { website_id, website_uuid, session },
} = req; } = req;
const { type, payload } = getJsonBody(req); const { type, payload } = getJsonBody(req);
@ -73,9 +73,9 @@ export default async (req, res) => {
const event_uuid = uuid(); const event_uuid = uuid();
if (type === 'pageview') { if (type === 'pageview') {
await savePageView(website_id, { session, url, referrer }); await savePageView(website_id, website_uuid, { session, url, referrer });
} else if (type === 'event') { } else if (type === 'event') {
await saveEvent(website_id, { await saveEvent(website_id, website_uuid, {
session, session,
event_uuid, event_uuid,
url, url,
@ -87,7 +87,12 @@ export default async (req, res) => {
} }
const token = createToken( const token = createToken(
{ website_id, session_id: session.session_id, session_uuid: session.session_uuid }, {
website_id,
website_uuid,
session_id: session.session_id,
session_uuid: session.session_uuid,
},
secret(), secret(),
); );

View File

@ -14,8 +14,9 @@ export default async (req, res) => {
const { id } = req.query; const { id } = req.query;
const websiteId = +id; const websiteId = +id;
const website_uuid = id;
const result = await getActiveVisitors(websiteId); const result = await getActiveVisitors(websiteId, website_uuid);
return ok(res, result); return ok(res, result);
} }

View File

@ -21,10 +21,11 @@ export default async (req, res) => {
} }
const websiteId = +id; const websiteId = +id;
const website_uuid = id;
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
const endDate = new Date(+end_at); const endDate = new Date(+end_at);
const events = await getEventMetrics(websiteId, startDate, endDate, tz, unit, { const events = await getEventMetrics(websiteId, website_uuid, startDate, endDate, tz, unit, {
url, url,
event_name, event_name,
}); });

View File

@ -44,6 +44,7 @@ export default async (req, res) => {
const { id, type, start_at, end_at, url, referrer, os, browser, device, country } = req.query; const { id, type, start_at, end_at, url, referrer, os, browser, device, country } = req.query;
const websiteId = +id; const websiteId = +id;
const website_uuid = id;
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
const endDate = new Date(+end_at); const endDate = new Date(+end_at);
@ -106,7 +107,7 @@ export default async (req, res) => {
query: type === 'query' && table !== 'event' ? true : undefined, query: type === 'query' && table !== 'event' ? true : undefined,
}; };
const data = await getPageviewMetrics(websiteId, { const data = await getPageviewMetrics(websiteId, website_uuid, {
startDate, startDate,
endDate, endDate,
column, column,

View File

@ -18,6 +18,7 @@ export default async (req, res) => {
req.query; req.query;
const websiteId = +id; const websiteId = +id;
const website_uuid = id;
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
const endDate = new Date(+end_at); const endDate = new Date(+end_at);
@ -26,7 +27,7 @@ export default async (req, res) => {
} }
const [pageviews, sessions] = await Promise.all([ const [pageviews, sessions] = await Promise.all([
getPageviewStats(websiteId, { getPageviewStats(websiteId, website_uuid, {
start_at: startDate, start_at: startDate,
end_at: endDate, end_at: endDate,
timezone: tz, timezone: tz,
@ -41,7 +42,7 @@ export default async (req, res) => {
country, country,
}, },
}), }),
getPageviewStats(websiteId, { getPageviewStats(websiteId, website_uuid, {
start_at: startDate, start_at: startDate,
end_at: endDate, end_at: endDate,
timezone: tz, timezone: tz,

View File

@ -14,6 +14,7 @@ export default async (req, res) => {
const { id, start_at, end_at, url, referrer, os, browser, device, country } = req.query; const { id, start_at, end_at, url, referrer, os, browser, device, country } = req.query;
const websiteId = +id; const websiteId = +id;
const website_uuid = id;
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
const endDate = new Date(+end_at); const endDate = new Date(+end_at);
@ -21,7 +22,7 @@ export default async (req, res) => {
const prevStartDate = new Date(+start_at - distance); const prevStartDate = new Date(+start_at - distance);
const prevEndDate = new Date(+end_at - distance); const prevEndDate = new Date(+end_at - distance);
const metrics = await getWebsiteStats(websiteId, { const metrics = await getWebsiteStats(websiteId, website_uuid, {
start_at: startDate, start_at: startDate,
end_at: endDate, end_at: endDate,
filters: { filters: {
@ -33,7 +34,7 @@ export default async (req, res) => {
country, country,
}, },
}); });
const prevPeriod = await getWebsiteStats(websiteId, { const prevPeriod = await getWebsiteStats(websiteId, website_uuid, {
start_at: prevStartDate, start_at: prevStartDate,
end_at: prevEndDate, end_at: prevEndDate,
filters: { filters: {

View File

@ -36,7 +36,7 @@ async function relationalQuery(
} }
async function clickhouseQuery( async function clickhouseQuery(
website_id, website_uuid,
start_at, start_at,
end_at, end_at,
timezone = 'UTC', timezone = 'UTC',
@ -44,7 +44,7 @@ async function clickhouseQuery(
filters = {}, filters = {},
) { ) {
const { rawQuery, getDateQuery, getBetweenDates, getFilterQuery } = clickhouse; const { rawQuery, getDateQuery, getBetweenDates, getFilterQuery } = clickhouse;
const params = [website_id]; const params = [website_uuid];
return rawQuery( return rawQuery(
`select `select

View File

@ -25,19 +25,23 @@ function relationalQuery(websites, start_at) {
} }
function clickhouseQuery(websites, start_at) { function clickhouseQuery(websites, start_at) {
const { rawQuery, getDateFormat } = clickhouse; const { rawQuery, getDateFormat, getCommaSeparatedStringFormat } = clickhouse;
return rawQuery( return rawQuery(
`select `select
event_uuid, event_id,
website_id, website_id,
session_uuid, session_id,
created_at, created_at,
url, url,
event_name event_name
from event from event
where event_name != '' where event_name != ''
and ${websites && websites.length > 0 ? `website_id in (${websites.join(',')})` : '0 = 0'} and ${
websites && websites.length > 0
? `website_id in (${getCommaSeparatedStringFormat(websites, websites.website_uuid)})`
: '0 = 0'
}
and created_at >= ${getDateFormat(start_at)}`, and created_at >= ${getDateFormat(start_at)}`,
); );
} }

View File

@ -32,14 +32,14 @@ async function relationalQuery(website_id, { session_id, url, event_name, event_
} }
async function clickhouseQuery( async function clickhouseQuery(
website_id, website_uuid,
{ session: { country, ...sessionArgs }, event_uuid, url, event_name, event_data }, { session: { country, ...sessionArgs }, event_uuid, url, event_name, event_data },
) { ) {
const { getDateFormat, sendMessage } = kafka; const { getDateFormat, sendMessage } = kafka;
const params = { const params = {
event_uuid, event_uuid,
website_id, website_uuid,
created_at: getDateFormat(new Date()), created_at: getDateFormat(new Date()),
url: url?.substring(0, URL_LENGTH), url: url?.substring(0, URL_LENGTH),
event_name: event_name?.substring(0, EVENT_NAME_LENGTH), event_name: event_name?.substring(0, EVENT_NAME_LENGTH),

View File

@ -34,9 +34,9 @@ async function relationalQuery(website_id, { startDate, endDate, column, table,
); );
} }
async function clickhouseQuery(website_id, { startDate, endDate, column, filters = {} }) { async function clickhouseQuery(website_uuid, { startDate, endDate, column, filters = {} }) {
const { rawQuery, parseFilters, getBetweenDates } = clickhouse; const { rawQuery, parseFilters, getBetweenDates } = clickhouse;
const params = [website_id]; const params = [website_uuid];
const { pageviewQuery, sessionQuery, eventQuery } = parseFilters(column, filters, params); const { pageviewQuery, sessionQuery, eventQuery } = parseFilters(column, filters, params);
return rawQuery( return rawQuery(

View File

@ -45,11 +45,11 @@ async function relationalQuery(
} }
async function clickhouseQuery( async function clickhouseQuery(
website_id, website_uuid,
{ start_at, end_at, timezone = 'UTC', unit = 'day', count = '*', filters = {} }, { start_at, end_at, timezone = 'UTC', unit = 'day', count = '*', filters = {} },
) { ) {
const { parseFilters, rawQuery, getDateStringQuery, getDateQuery, getBetweenDates } = clickhouse; const { parseFilters, rawQuery, getDateStringQuery, getDateQuery, getBetweenDates } = clickhouse;
const params = [website_id]; const params = [website_uuid];
const { pageviewQuery, sessionQuery } = parseFilters(null, filters, params); const { pageviewQuery, sessionQuery } = parseFilters(null, filters, params);
return rawQuery( return rawQuery(
@ -59,7 +59,7 @@ async function clickhouseQuery(
from from
(select (select
${getDateQuery('created_at', unit, timezone)} t, ${getDateQuery('created_at', unit, timezone)} t,
count(${count !== '*' ? 'distinct session_uuid' : count}) y count(${count !== '*' ? 'distinct session_id' : count}) y
from event from event
where event_name = '' where event_name = ''
and website_id= $1 and website_id= $1

View File

@ -25,15 +25,21 @@ async function relationalQuery(websites, start_at) {
} }
async function clickhouseQuery(websites, start_at) { async function clickhouseQuery(websites, start_at) {
const { getCommaSeparatedStringFormat } = clickhouse;
return clickhouse.rawQuery( return clickhouse.rawQuery(
`select `select
website_id, website_id,
session_uuid, session_id,
created_at, created_at,
url url
from event from event
where event_name = '' where event_name = ''
and ${websites && websites.length > 0 ? `website_id in (${websites.join(',')})` : '0 = 0'} and ${
websites && websites.length > 0
? `website_id in (${getCommaSeparatedStringFormat(websites, websites.website_uuid)})`
: '0 = 0'
}
and created_at >= ${clickhouse.getDateFormat(start_at)}`, and created_at >= ${clickhouse.getDateFormat(start_at)}`,
); );
} }

View File

@ -22,12 +22,12 @@ async function relationalQuery(website_id, { session: { session_id }, url, refer
} }
async function clickhouseQuery( async function clickhouseQuery(
website_id, website_uuid,
{ session: { country, ...sessionArgs }, url, referrer }, { session: { country, ...sessionArgs }, url, referrer },
) { ) {
const { getDateFormat, sendMessage } = kafka; const { getDateFormat, sendMessage } = kafka;
const params = { const params = {
website_id: website_id, website_id: website_uuid,
created_at: getDateFormat(new Date()), created_at: getDateFormat(new Date()),
url: url?.substring(0, URL_LENGTH), url: url?.substring(0, URL_LENGTH),
referrer: referrer?.substring(0, URL_LENGTH), referrer: referrer?.substring(0, URL_LENGTH),

View File

@ -39,14 +39,14 @@ async function relationalQuery(website_id, data) {
} }
async function clickhouseQuery( async function clickhouseQuery(
website_id, website_uuid,
{ session_uuid, hostname, browser, os, screen, language, country, device }, { session_uuid, hostname, browser, os, screen, language, country, device },
) { ) {
const { getDateFormat, sendMessage } = kafka; const { getDateFormat, sendMessage } = kafka;
const params = { const params = {
session_uuid, session_uuid,
website_id, website_uuid,
created_at: getDateFormat(new Date()), created_at: getDateFormat(new Date()),
hostname, hostname,
browser, browser,

View File

@ -23,12 +23,12 @@ async function relationalQuery(website_id) {
); );
} }
async function clickhouseQuery(website_id) { async function clickhouseQuery(website_uuid) {
const { rawQuery, getDateFormat } = clickhouse; const { rawQuery, getDateFormat } = clickhouse;
const params = [website_id]; const params = [website_uuid];
return rawQuery( return rawQuery(
`select count(distinct session_uuid) x `select count(distinct session_id) x
from event from event
where website_id = $1 where website_id = $1
and created_at >= ${getDateFormat(subMinutes(new Date(), 5))}`, and created_at >= ${getDateFormat(subMinutes(new Date(), 5))}`,

View File

@ -41,19 +41,19 @@ async function relationalQuery(website_id, { start_at, end_at, filters = {} }) {
); );
} }
async function clickhouseQuery(website_id, { start_at, end_at, filters = {} }) { async function clickhouseQuery(website_uuid, { start_at, end_at, filters = {} }) {
const { rawQuery, getDateQuery, getBetweenDates, parseFilters } = clickhouse; const { rawQuery, getDateQuery, getBetweenDates, parseFilters } = clickhouse;
const params = [website_id]; const params = [website_uuid];
const { pageviewQuery, sessionQuery } = parseFilters(null, filters, params); const { pageviewQuery, sessionQuery } = parseFilters(null, filters, params);
return rawQuery( return rawQuery(
`select `select
sum(t.c) as "pageviews", sum(t.c) as "pageviews",
count(distinct t.session_uuid) as "uniques", count(distinct t.session_id) as "uniques",
sum(if(t.c = 1, 1, 0)) as "bounces", sum(if(t.c = 1, 1, 0)) as "bounces",
sum(if(max_time < min_time + interval 1 hour, max_time-min_time, 0)) as "totaltime" sum(if(max_time < min_time + interval 1 hour, max_time-min_time, 0)) as "totaltime"
from ( from (
select session_uuid, select session_id,
${getDateQuery('created_at', 'day')} time_series, ${getDateQuery('created_at', 'day')} time_series,
count(*) c, count(*) c,
min(created_at) min_time, min(created_at) min_time,
@ -64,7 +64,7 @@ async function clickhouseQuery(website_id, { start_at, end_at, filters = {} }) {
and ${getBetweenDates('created_at', start_at, end_at)} and ${getBetweenDates('created_at', start_at, end_at)}
${pageviewQuery} ${pageviewQuery}
${sessionQuery} ${sessionQuery}
group by session_uuid, time_series group by session_id, time_series
) t;`, ) t;`,
params, params,
); );