umami/queries/analytics/pageviews/getPageviewMetrics.ts

119 lines
2.8 KiB
TypeScript
Raw Normal View History

import prisma from 'lib/prisma';
import clickhouse from 'lib/clickhouse';
import { runQuery, CLICKHOUSE, PRISMA } from 'lib/db';
2023-07-26 07:50:55 +02:00
import { EVENT_TYPE } from 'lib/constants';
2023-07-26 08:59:08 +02:00
import { loadWebsite } from 'lib/load';
import { maxDate } from 'lib/date';
export async function getPageviewMetrics(
...args: [
websiteId: string,
2023-04-02 00:44:30 +02:00
criteria: {
startDate: Date;
endDate: Date;
2023-04-02 00:44:30 +02:00
column: string;
filters: object;
},
]
) {
return runQuery({
[PRISMA]: () => relationalQuery(...args),
[CLICKHOUSE]: () => clickhouseQuery(...args),
});
}
async function relationalQuery(
websiteId: string,
2023-04-02 00:44:30 +02:00
criteria: {
startDate: Date;
endDate: Date;
2023-04-02 00:44:30 +02:00
column: string;
filters: object;
},
) {
2023-04-02 00:44:30 +02:00
const { startDate, endDate, filters = {}, column } = criteria;
2023-07-25 08:06:16 +02:00
const { rawQuery, parseFilters } = prisma;
2023-04-02 00:44:30 +02:00
const website = await loadWebsite(websiteId);
2023-07-25 08:06:16 +02:00
const params: any = {
websiteId,
2023-07-26 08:59:08 +02:00
startDate: maxDate(startDate, website.resetAt),
endDate,
2023-07-25 08:06:16 +02:00
eventType: column === 'event_name' ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView,
2023-07-31 20:42:47 +02:00
...filters,
2023-07-25 08:06:16 +02:00
};
2023-04-02 00:44:30 +02:00
2023-04-02 19:00:28 +02:00
let excludeDomain = '';
2023-04-02 00:44:30 +02:00
if (column === 'referrer_domain') {
excludeDomain =
2023-07-25 08:06:16 +02:00
'and (website_event.referrer_domain != {{domain}} or website_event.referrer_domain is null)';
params.domain = website.domain;
2023-04-02 00:44:30 +02:00
}
2023-07-25 08:06:16 +02:00
const { filterQuery, joinSession } = parseFilters(filters);
return rawQuery(
2023-07-25 08:06:16 +02:00
`
select ${column} x, count(*) y
from website_event
${joinSession}
2023-07-25 08:06:16 +02:00
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
and event_type = {{eventType}}
2023-04-02 19:00:28 +02:00
${excludeDomain}
${filterQuery}
group by 1
2023-03-05 22:30:21 +01:00
order by 2 desc
2023-07-25 08:06:16 +02:00
limit 100
`,
params,
);
}
async function clickhouseQuery(
websiteId: string,
2023-04-02 00:44:30 +02:00
criteria: {
startDate: Date;
endDate: Date;
2023-04-02 00:44:30 +02:00
column: string;
filters: object;
},
) {
2023-04-02 00:44:30 +02:00
const { startDate, endDate, filters = {}, column } = criteria;
2023-07-25 08:06:16 +02:00
const { rawQuery, parseFilters } = clickhouse;
2023-04-02 00:44:30 +02:00
const website = await loadWebsite(websiteId);
const params = {
websiteId,
2023-07-26 08:59:08 +02:00
startDate: maxDate(startDate, website.resetAt),
2023-07-25 08:06:16 +02:00
endDate,
2023-04-02 00:44:30 +02:00
eventType: column === 'event_name' ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView,
domain: undefined,
};
2023-04-02 00:44:30 +02:00
let excludeDomain = '';
if (column === 'referrer_domain') {
excludeDomain = 'and referrer_domain != {domain:String}';
params.domain = website.domain;
}
const { filterQuery } = parseFilters(filters, params);
return rawQuery(
2023-07-25 08:06:16 +02:00
`
select ${column} x, count(*) y
2023-03-29 20:06:12 +02:00
from website_event
where website_id = {websiteId:UUID}
2023-07-25 08:06:16 +02:00
and created_at between {startDate:DateTime} and {endDate:DateTime}
and event_type = {eventType:UInt32}
2023-04-02 00:44:30 +02:00
${excludeDomain}
${filterQuery}
group by x
2023-03-05 22:30:21 +01:00
order by y desc
2023-07-25 08:06:16 +02:00
limit 100
`,
params,
);
}