Compare commits

..

No commits in common. "74972bccb110ceff7026cce87a98e2a73943ae63" and "1d3e980eedd6908a269fc4be12ae90efce0506d8" have entirely different histories.

24 changed files with 175 additions and 299 deletions

View file

@ -4,7 +4,7 @@ import { useSpring, config } from '@react-spring/web';
import { Grid, Row, Column, Text } from '@umami/react-zen'; import { Grid, Row, Column, Text } from '@umami/react-zen';
import { AnimatedDiv } from '@/components/common/AnimatedDiv'; import { AnimatedDiv } from '@/components/common/AnimatedDiv';
import { Empty } from '@/components/common/Empty'; import { Empty } from '@/components/common/Empty';
import { useMessages, useMobile } from '@/components/hooks'; import { useMessages } from '@/components/hooks';
import { formatLongCurrency, formatLongNumber } from '@/lib/format'; import { formatLongCurrency, formatLongNumber } from '@/lib/format';
const ITEM_SIZE = 30; const ITEM_SIZE = 30;
@ -42,7 +42,6 @@ export function ListTable({
currency, currency,
}: ListTableProps) { }: ListTableProps) {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { isMobile } = useMobile();
const getRow = (row: ListData, index: number) => { const getRow = (row: ListData, index: number) => {
const { label, count, percent } = row; const { label, count, percent } = row;
@ -57,7 +56,6 @@ export function ListTable({
showPercentage={showPercentage} showPercentage={showPercentage}
change={renderChange ? renderChange(row, index) : null} change={renderChange ? renderChange(row, index) : null}
currency={currency} currency={currency}
isMobile={isMobile}
/> />
); );
}; };
@ -101,7 +99,6 @@ const AnimatedRow = ({
animate, animate,
showPercentage = true, showPercentage = true,
currency, currency,
isMobile,
}) => { }) => {
const props = useSpring({ const props = useSpring({
width: percent, width: percent,
@ -120,7 +117,7 @@ const AnimatedRow = ({
gap gap
> >
<Row alignItems="center"> <Row alignItems="center">
<Text truncate={true} style={{ maxWidth: isMobile ? '200px' : '400px' }}> <Text truncate={true} style={{ maxWidth: '400px' }}>
{label} {label}
</Text> </Text>
</Row> </Row>

View file

@ -118,7 +118,6 @@ function getCohortQuery(filters: QueryFilters = {}) {
(select distinct website_event.session_id (select distinct website_event.session_id
from website_event from website_event
join session on session.session_id = website_event.session_id join session on session.session_id = website_event.session_id
and session.website_id = website_event.website_id
where website_event.website_id = {{websiteId}} where website_event.website_id = {{websiteId}}
and website_event.created_at between {{cohort_startDate}} and {{cohort_endDate}} and website_event.created_at between {{cohort_startDate}} and {{cohort_endDate}}
${filterQuery} ${filterQuery}
@ -166,7 +165,7 @@ function parseFilters(filters: Record<string, any>, options?: QueryOptions) {
return { return {
joinSessionQuery: joinSessionQuery:
options?.joinSession || joinSession options?.joinSession || joinSession
? `inner join session on website_event.session_id = session.session_id and website_event.website_id = session.website_id` ? `inner join session on website_event.session_id = session.session_id`
: '', : '',
dateQuery: getDateQuery(filters), dateQuery: getDateQuery(filters),
filterQuery: getFilterQuery(filters, options), filterQuery: getFilterQuery(filters, options),
@ -226,8 +225,8 @@ async function pagedQuery<T>(model: string, criteria: T, filters?: QueryFilters)
async function pagedRawQuery( async function pagedRawQuery(
query: string, query: string,
queryParams: Record<string, any>,
filters: QueryFilters, filters: QueryFilters,
queryParams: Record<string, any>,
name?: string, name?: string,
) { ) {
const { page = 1, pageSize, orderBy, sortDescending = false } = filters; const { page = 1, pageSize, orderBy, sortDescending = false } = filters;

View file

@ -19,17 +19,17 @@ async function relationalQuery(websiteId: string, eventId: string) {
return rawQuery( return rawQuery(
` `
select website_id as "websiteId", select website_id as websiteId,
session_id as "sessionId", session_id as sessionId,
event_id as "eventId", event_id as eventId,
url_path as "urlPath", url_path as urlPath,
event_name as "eventName", event_name as eventName,
data_key as "dataKey", data_key as dataKey,
string_value as "stringValue", string_value as stringValue,
number_value as "numberValue", number_value as numberValue,
date_value as "dateValue", date_value as dateValue,
data_type as "dataType", data_type as dataType,
created_at as "createdAt" created_at as createdAt
from event_data from event_data
website_id = {{websiteId::uuid}} website_id = {{websiteId::uuid}}
event_id = {{eventId::uuid}} event_id = {{eventId::uuid}}

View file

@ -37,7 +37,7 @@ async function relationalQuery(
) { ) {
const { type, limit = 500, offset = 0 } = parameters; const { type, limit = 500, offset = 0 } = parameters;
const column = FILTER_COLUMNS[type] || type; const column = FILTER_COLUMNS[type] || type;
const { rawQuery, parseFilters, getTimestampDiffSQL } = prisma; const { rawQuery, parseFilters } = prisma;
const { filterQuery, cohortQuery, joinSessionQuery, queryParams } = parseFilters( const { filterQuery, cohortQuery, joinSessionQuery, queryParams } = parseFilters(
{ {
...filters, ...filters,
@ -49,31 +49,16 @@ async function relationalQuery(
return rawQuery( return rawQuery(
` `
select select ${column} x,
name, count(*) as y
sum(t.c) as "pageviews", from website_event
count(distinct t.session_id) as "visitors", ${cohortQuery}
count(distinct t.visit_id) as "visits", ${joinSessionQuery}
sum(case when t.c = 1 then 1 else 0 end) as "bounces", where website_event.website_id = {{websiteId::uuid}}
sum(${getTimestampDiffSQL('t.min_time', 't.max_time')}) as "totaltime" and website_event.created_at between {{startDate}} and {{endDate}}
from ( ${filterQuery}
select group by 1
${column} name, order by 2 desc
website_event.session_id,
website_event.visit_id,
count(*) as "c",
min(website_event.created_at) as "min_time",
max(website_event.created_at) as "max_time"
from website_event
${cohortQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
${filterQuery}
group by name, website_event.session_id, website_event.visit_id
) as t
group by name
order by visitors desc, visits desc
limit ${limit} limit ${limit}
offset ${offset} offset ${offset}
`, `,

View file

@ -18,6 +18,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
const { filterQuery, dateQuery, cohortQuery, queryParams } = parseFilters({ const { filterQuery, dateQuery, cohortQuery, queryParams } = parseFilters({
...filters, ...filters,
websiteId, websiteId,
search: `%${search}%`,
}); });
const searchQuery = search const searchQuery = search
@ -28,33 +29,32 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
return pagedRawQuery( return pagedRawQuery(
` `
select select
website_event.event_id as "id", event_id as "id",
website_event.website_id as "websiteId", website_id as "websiteId",
website_event.session_id as "sessionId", session_id as "sessionId",
website_event.created_at as "createdAt", created_at as "createdAt",
website_event.hostname, hostname,
website_event.url_path as "urlPath", url_path as "urlPath",
website_event.url_query as "urlQuery", url_query as "urlQuery",
website_event.referrer_path as "referrerPath", referrer_path as "referrerPath",
website_event.referrer_query as "referrerQuery", referrer_query as "referrerQuery",
website_event.referrer_domain as "referrerDomain", referrer_domain as "referrerDomain",
session.country as country, country as country,
city as city, city as city,
device as device, device as device,
os as os, os as os,
browser as browser, browser as browser,
page_title as "pageTitle", page_title as "pageTitle",
website_event.event_type as "eventType", event_type as "eventType",
website_event.event_name as "eventName" event_name as "eventName"
from website_event from website_event
${cohortQuery} ${cohortQuery}
join session on session.session_id = website_event.session_id join session on website_event.session_id = session.session_id
and session.website_id = website_event.website_id where website_id = {{websiteId::uuid}}
where website_event.website_id = {{websiteId::uuid}}
${dateQuery} ${dateQuery}
${filterQuery} ${filterQuery}
${searchQuery} ${searchQuery}
order by website_event.created_at desc order by created_at desc
`, `,
queryParams, queryParams,
filters, filters,

View file

@ -18,7 +18,7 @@ async function relationalQuery(websiteId: string) {
const result = await rawQuery( const result = await rawQuery(
` `
select count(distinct session_id) as "visitors" select count(distinct session_id) as visitors
from website_event from website_event
where website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and created_at >= {{startDate}} and created_at >= {{startDate}}

View file

@ -40,7 +40,7 @@ async function relationalQuery(
websiteId: string, websiteId: string,
filters: QueryFilters, filters: QueryFilters,
): Promise<ChannelExpandedMetricsData[]> { ): Promise<ChannelExpandedMetricsData[]> {
const { rawQuery, parseFilters, getTimestampDiffSQL } = prisma; const { rawQuery, parseFilters } = prisma;
const { queryParams, filterQuery, joinSessionQuery, cohortQuery, dateQuery } = parseFilters({ const { queryParams, filterQuery, joinSessionQuery, cohortQuery, dateQuery } = parseFilters({
...filters, ...filters,
websiteId, websiteId,
@ -48,70 +48,40 @@ async function relationalQuery(
return rawQuery( return rawQuery(
` `
WITH prefix AS ( WITH channels as (
select case when website_event.utm_medium LIKE 'p%' OR select case when ${toPostgresPositionClause('utm_medium', ['cp', 'ppc', 'retargeting', 'paid'])} then 'paid' else 'organic' end prefix,
website_event.utm_medium LIKE '%ppc%' OR case
website_event.utm_medium LIKE '%retargeting%' OR when referrer_domain = '' and url_query = '' then 'direct'
website_event.utm_medium LIKE '%paid%' then 'paid' else 'organic' end prefix, when ${toPostgresPositionClause('url_query', PAID_AD_PARAMS)} then 'paidAds'
website_event.referrer_domain, when ${toPostgresPositionClause('utm_medium', ['referral', 'app', 'link'])} then 'referral'
website_event.url_query, when position(utm_medium, 'affiliate') > 0 then 'affiliate'
website_event.utm_medium, when position(utm_medium, 'sms') > 0 or position(utm_source, 'sms') > 0 then 'sms'
website_event.utm_source, when ${toPostgresPositionClause('referrer_domain', SEARCH_DOMAINS)} or position(utm_medium, 'organic') > 0 then concat(prefix, 'Search')
website_event.session_id, when ${toPostgresPositionClause('referrer_domain', SOCIAL_DOMAINS)} then concat(prefix, 'Social')
website_event.visit_id, when ${toPostgresPositionClause('referrer_domain', EMAIL_DOMAINS)} or position(utm_medium, 'mail') > 0 then 'email'
count(*) c, when ${toPostgresPositionClause('referrer_domain', SHOPPING_DOMAINS)} or position(utm_medium, 'shop') > 0 then concat(prefix, 'Shopping')
min(website_event.created_at) min_time, when ${toPostgresPositionClause('referrer_domain', VIDEO_DOMAINS)} or position(utm_medium, 'video') > 0 then concat(prefix, 'Video')
max(website_event.created_at) max_time else '' end AS x,
from website_event count(distinct session_id) y
${cohortQuery} from website_event
${joinSessionQuery} ${cohortQuery}
where website_event.website_id = {{websiteId::uuid}} ${joinSessionQuery}
and website_event.event_type != 2 where website_event.website_id = {{websiteId::uuid}}
${dateQuery} and website_event.event_type != 2
${filterQuery} ${dateQuery}
group by prefix, ${filterQuery}
website_event.referrer_domain, group by 1, 2
website_event.url_query, order by y desc)
website_event.utm_medium,
website_event.utm_source, select x, sum(y) y
website_event.session_id, from channels
website_event.visit_id), where x != ''
group by x
channels as ( order by y desc;
select case `,
when referrer_domain = '' and url_query = '' then 'direct'
when ${toPostgresPositionClause('url_query', PAID_AD_PARAMS)} then 'paidAds'
when ${toPostgresPositionClause('utm_medium', ['referral', 'app', 'link'])} then 'referral'
when utm_medium ilike '%affiliate%' then 'affiliate'
when utm_medium ilike '%sms%' or utm_source ilike '%sms%' then 'sms'
when ${toPostgresPositionClause('referrer_domain', SEARCH_DOMAINS)} or utm_medium ilike '%organic%' then concat(prefix, 'Search')
when ${toPostgresPositionClause('referrer_domain', SOCIAL_DOMAINS)} then concat(prefix, 'Social')
when ${toPostgresPositionClause('referrer_domain', EMAIL_DOMAINS)} or utm_medium ilike '%mail%' then 'email'
when ${toPostgresPositionClause('referrer_domain', SHOPPING_DOMAINS)} or utm_medium ilike '%shop%' then concat(prefix, 'Shopping')
when ${toPostgresPositionClause('referrer_domain', VIDEO_DOMAINS)} or utm_medium ilike '%video%' then concat(prefix, 'Video')
else '' end AS name,
session_id,
visit_id,
c,
min_time,
max_time
from prefix)
select
name,
sum(c) as "pageviews",
count(distinct session_id) as "visitors",
count(distinct visit_id) as "visits",
sum(case when c = 1 then 1 else 0 end) as "bounces",
sum(${getTimestampDiffSQL('min_time', 'max_time')}) as "totaltime"
from channels
where name != ''
group by name
order by visitors desc, visits desc
`,
queryParams, queryParams,
FUNCTION_NAME, FUNCTION_NAME,
).then(results => results.map(item => ({ ...item, y: Number(item.y) }))); );
} }
async function clickhouseQuery( async function clickhouseQuery(
@ -186,5 +156,5 @@ function toClickHouseStringArray(arr: string[]): string {
} }
function toPostgresPositionClause(column: string, arr: string[]) { function toPostgresPositionClause(column: string, arr: string[]) {
return arr.map(val => `${column} ilike '%${val.replace(/'/g, "''")}%'`).join(' OR\n '); return arr.map(val => `position(${column}, '${val.replace(/'/g, "''")}') > 0`).join(' OR\n ');
} }

View file

@ -29,40 +29,29 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
return rawQuery( return rawQuery(
` `
WITH prefix AS ( WITH channels as (
select case when website_event.utm_medium LIKE 'p%' OR select case when ${toPostgresPositionClause('utm_medium', ['cp', 'ppc', 'retargeting', 'paid'])} then 'paid' else 'organic' end prefix,
website_event.utm_medium LIKE '%ppc%' OR case
website_event.utm_medium LIKE '%retargeting%' OR when referrer_domain = '' and url_query = '' then 'direct'
website_event.utm_medium LIKE '%paid%' then 'paid' else 'organic' end prefix, when ${toPostgresPositionClause('url_query', PAID_AD_PARAMS)} then 'paidAds'
website_event.referrer_domain, when ${toPostgresPositionClause('utm_medium', ['referral', 'app', 'link'])} then 'referral'
website_event.url_query, when position(utm_medium, 'affiliate') > 0 then 'affiliate'
website_event.utm_medium, when position(utm_medium, 'sms') > 0 or position(utm_source, 'sms') > 0 then 'sms'
website_event.utm_source, when ${toPostgresPositionClause('referrer_domain', SEARCH_DOMAINS)} or position(utm_medium, 'organic') > 0 then concat(prefix, 'Search')
website_event.session_id when ${toPostgresPositionClause('referrer_domain', SOCIAL_DOMAINS)} then concat(prefix, 'Social')
when ${toPostgresPositionClause('referrer_domain', EMAIL_DOMAINS)} or position(utm_medium, 'mail') > 0 then 'email'
when ${toPostgresPositionClause('referrer_domain', SHOPPING_DOMAINS)} or position(utm_medium, 'shop') > 0 then concat(prefix, 'Shopping')
when ${toPostgresPositionClause('referrer_domain', VIDEO_DOMAINS)} or position(utm_medium, 'video') > 0 then concat(prefix, 'Video')
else '' end AS x,
count(distinct session_id) y
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_event.website_id = {{websiteId::uuid}}
and website_event.event_type != 2 and website_event.event_type != 2
${dateQuery} ${dateQuery}
${filterQuery}), ${filterQuery}
group by 1, 2
channels as (
select case
when referrer_domain = '' and url_query = '' then 'direct'
when ${toPostgresLikeClause('url_query', PAID_AD_PARAMS)} then 'paidAds'
when ${toPostgresLikeClause('utm_medium', ['referral', 'app', 'link'])} then 'referral'
when utm_medium ilike '%affiliate%' then 'affiliate'
when utm_medium ilike '%sms%' or utm_source ilike '%sms%' then 'sms'
when ${toPostgresLikeClause('referrer_domain', SEARCH_DOMAINS)} or utm_medium ilike '%organic%' then concat(prefix, 'Search')
when ${toPostgresLikeClause('referrer_domain', SOCIAL_DOMAINS)} then concat(prefix, 'Social')
when ${toPostgresLikeClause('referrer_domain', EMAIL_DOMAINS)} or utm_medium ilike '%mail%' then 'email'
when ${toPostgresLikeClause('referrer_domain', SHOPPING_DOMAINS)} or utm_medium ilike '%shop%' then concat(prefix, 'Shopping')
when ${toPostgresLikeClause('referrer_domain', VIDEO_DOMAINS)} or utm_medium ilike '%video%' then concat(prefix, 'Video')
else '' end AS x,
count(distinct session_id) y
from prefix
group by 1
order by y desc) order by y desc)
select x, sum(y) y select x, sum(y) y
@ -73,7 +62,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
`, `,
queryParams, queryParams,
FUNCTION_NAME, FUNCTION_NAME,
).then(results => results.map(item => ({ ...item, y: Number(item.y) }))); );
} }
async function clickhouseQuery( async function clickhouseQuery(
@ -137,6 +126,6 @@ function toClickHouseStringArray(arr: string[]): string {
return arr.map(p => `'${p.replace(/'/g, "\\'")}'`).join(', '); return arr.map(p => `'${p.replace(/'/g, "\\'")}'`).join(', ');
} }
function toPostgresLikeClause(column: string, arr: string[]) { function toPostgresPositionClause(column: string, arr: string[]) {
return arr.map(val => `${column} ilike '%${val.replace(/'/g, "''")}%'`).join(' OR\n '); return arr.map(val => `position(${column}, '${val.replace(/'/g, "''")}') > 0`).join(' OR\n ');
} }

View file

@ -35,7 +35,6 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
${cohortQuery} ${cohortQuery}
inner join session inner join session
on session.session_id = website_event.session_id on session.session_id = website_event.session_id
and session.website_id = website_event.website_id
where website_event.website_id = {{websiteId::uuid}} where website_event.website_id = {{websiteId::uuid}}
${filterQuery} ${filterQuery}
${dateQuery} ${dateQuery}

View file

@ -51,7 +51,6 @@ async function relationalQuery(websiteId: string, column: string, filters: Query
from website_event from website_event
inner join session inner join session
on session.session_id = website_event.session_id on session.session_id = website_event.session_id
and session.website_id = website_event.website_id
where website_event.website_id = {{websiteId::uuid}} where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and website_event.created_at between {{startDate}} and {{endDate}}
${searchQuery} ${searchQuery}

View file

@ -20,8 +20,8 @@ async function relationalQuery(websiteId: string) {
const result = await rawQuery( const result = await rawQuery(
` `
select select
min(created_at) as "startDate", min(created_at) as startDate,
max(created_at) as "endDate" max(created_at) as endDate
from website_event from website_event
where website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and created_at >= {{startDate}} and created_at >= {{startDate}}

View file

@ -24,13 +24,13 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
return rawQuery( return rawQuery(
` `
select select
${getDateWeeklySQL('website_event.created_at', timezone)} as time, ${getDateWeeklySQL('created_at', timezone)} as time,
count(distinct website_event.session_id) as value count(distinct session_id) as value
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}
${filterQuery} ${filterQuery}
group by time group by time
order by 2 order by 2

View file

@ -36,8 +36,8 @@ async function relationalQuery(
filters: QueryFilters, filters: QueryFilters,
): Promise<PageviewExpandedMetricsData[]> { ): Promise<PageviewExpandedMetricsData[]> {
const { type, limit = 500, offset = 0 } = parameters; const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type; const column = FILTER_COLUMNS[type] || type;
const { rawQuery, parseFilters, getTimestampDiffSQL } = prisma; const { rawQuery, parseFilters } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters( const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters(
{ {
...filters, ...filters,
@ -52,9 +52,6 @@ async function relationalQuery(
if (column === 'referrer_domain') { if (column === 'referrer_domain') {
excludeDomain = `and website_event.referrer_domain != website_event.hostname excludeDomain = `and website_event.referrer_domain != website_event.hostname
and website_event.referrer_domain != ''`; and website_event.referrer_domain != ''`;
if (type === 'domain') {
column = toPostgresGroupedReferrer(GROUPED_DOMAINS);
}
} }
if (type === 'entry' || type === 'exit') { if (type === 'entry' || type === 'exit') {
@ -77,35 +74,19 @@ async function relationalQuery(
return rawQuery( return rawQuery(
` `
select select ${column} x,
name, count(distinct website_event.session_id) as y
sum(t.c) as "pageviews", from website_event
count(distinct t.session_id) as "visitors", ${cohortQuery}
count(distinct t.visit_id) as "visits", ${joinSessionQuery}
sum(case when t.c = 1 then 1 else 0 end) as "bounces", ${entryExitQuery}
sum(${getTimestampDiffSQL('t.min_time', 't.max_time')}) as "totaltime" where website_event.website_id = {{websiteId::uuid}}
from (
select
${column} name,
website_event.session_id,
website_event.visit_id,
count(*) as "c",
min(website_event.created_at) as "min_time",
max(website_event.created_at) as "max_time"
from website_event
${cohortQuery}
${joinSessionQuery}
${entryExitQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and website_event.created_at between {{startDate}} and {{endDate}}
and website_event.event_type != 2 and website_event.event_type != 2
${excludeDomain} ${excludeDomain}
${filterQuery} ${filterQuery}
group by name, website_event.session_id, website_event.visit_id group by 1
) as t order by 2 desc
where name != ''
group by name
order by visitors desc, visits desc
limit ${limit} limit ${limit}
offset ${offset} offset ${offset}
`, `,
@ -205,23 +186,3 @@ export function toClickHouseGroupedReferrer(
'END', 'END',
].join('\n'); ].join('\n');
} }
export function toPostgresGroupedReferrer(
domains: any[],
column: string = 'referrer_domain',
): string {
return [
'CASE',
...domains.map(group => {
const matches = Array.isArray(group.match) ? group.match : [group.match];
return `WHEN ${toPostgresLikeClause(column, matches)} THEN '${group.domain}'`;
}),
" ELSE 'Other'",
'END',
].join('\n');
}
function toPostgresLikeClause(column: string, arr: string[]) {
return arr.map(val => `${column} ilike '%${val.replace(/'/g, "''")}%'`).join(' OR\n ');
}

View file

@ -69,14 +69,14 @@ async function relationalQuery(
const eventQuery = `WITH events AS ( const eventQuery = `WITH events AS (
select distinct select distinct
website_event.session_id, session_id,
max(website_event.created_at) max_dt max(created_at) max_dt
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}
and website_event.${column} = {{step}} and ${column} = {{step}}
${filterQuery} ${filterQuery}
group by 1),`; group by 1),`;
@ -234,14 +234,14 @@ async function relationalQuery(
` `
select select
count(*) as "pageviews", count(*) as "pageviews",
count(distinct website_event.session_id) as "visitors", count(distinct session_id) as "visitors",
count(distinct website_event.visit_id) as "visits" count(distinct visit_id) as "visits"
from website_event from website_event
${joinSessionQuery} ${joinSessionQuery}
${cohortQuery} ${cohortQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}
and website_event.${column} = {{step}} and ${column} = {{step}}
${filterQuery} ${filterQuery}
`, `,
queryParams, queryParams,

View file

@ -67,12 +67,12 @@ async function relationalQuery(
if (levelNumber === 1) { if (levelNumber === 1) {
pv.levelOneQuery = ` pv.levelOneQuery = `
WITH level1 AS ( WITH level1 AS (
select distinct website_event.session_id, website_event.created_at select distinct session_id, created_at
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}
and ${column} ${operator} {{${i}}} and ${column} ${operator} {{${i}}}
${filterQuery} ${filterQuery}
)`; )`;

View file

@ -42,26 +42,26 @@ async function relationalQuery(
return rawQuery( return rawQuery(
` `
select count(distinct website_event.session_id) as num, select count(*) as num,
( (
select count(distinct website_event.session_id) select count(distinct session_id)
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
${dateQuery} ${dateQuery}
${filterQuery} ${filterQuery}
) as total ) as total
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and ${column} = {{value}} and ${column} = {{value}}
${dateQuery} ${dateQuery}
${filterQuery} ${filterQuery}
`, `,
queryParams, queryParams,
).then(results => results?.[0]); );
} }
async function clickhouseQuery( async function clickhouseQuery(
@ -84,7 +84,7 @@ async function clickhouseQuery(
return rawQuery( return rawQuery(
` `
select count(distinct session_id) as num, select count(*) as num,
( (
select count(distinct session_id) select count(distinct session_id)
from website_event from website_event

View file

@ -117,16 +117,16 @@ async function relationalQuery(
` `
WITH events AS ( WITH events AS (
select distinct select distinct
website_event.visit_id, visit_id,
website_event.referrer_path, referrer_path,
coalesce(nullIf(website_event.event_name, ''), website_event.url_path) event, coalesce(nullIf(event_name, ''), url_path) event,
row_number() OVER (PARTITION BY visit_id ORDER BY website_event.created_at) AS event_number row_number() OVER (PARTITION BY visit_id ORDER BY created_at) AS event_number
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}),
${filterQuery}), ${filterQuery}
${sequenceQuery} ${sequenceQuery}
select * select *
from sequences from sequences

View file

@ -37,13 +37,13 @@ async function relationalQuery(
return rawQuery( return rawQuery(
` `
select website_event.${column} utm, count(*) as views select ${column} utm, count(*) as views
from website_event from website_event
${cohortQuery} ${cohortQuery}
${joinSessionQuery} ${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}
and coalesce(website_event.${column}, '') != '' and coalesce(${column}, '') != ''
${filterQuery} ${filterQuery}
group by 1 group by 1
order by 2 desc order by 2 desc

View file

@ -21,23 +21,20 @@ async function relationalQuery(websiteId: string, sessionId: string, filters: Qu
return rawQuery( return rawQuery(
` `
select select
created_at as "createdAt", created_at as createdAt,
url_path as "urlPath", url_path as urlPath,
url_query as "urlQuery", url_query as urlQuery,
referrer_domain as "referrerDomain", referrer_domain as referrerDomain,
event_id as "eventId", event_id as eventId,
event_type as "eventType", event_type as eventType,
event_name as "eventName", event_name as eventName,
visit_id as "visitId", visit_id as visitId,
event_id IN (select event_id event_id IN (SELECT event_id FROM event_data) AS hasData
from event_data from website_event e
where website_id = {{websiteId::uuid}} where e.website_id = {websiteId:UUID}
and session_id = {{sessionId::uuid}}) AS "hasData" and e.session_id = {sessionId:UUID}
from website_event and e.created_at between {startDate:DateTime64} and {endDate:DateTime64}
where website_id = {{websiteId::uuid}} order by e.created_at desc
and session_id = {{sessionId::uuid}}
and created_at between {{startDate}} and {{endDate}}
order by created_at desc
limit 500 limit 500
`, `,
{ websiteId, sessionId, startDate, endDate }, { websiteId, sessionId, startDate, endDate },

View file

@ -31,7 +31,6 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
${joinSessionQuery} ${joinSessionQuery}
join session_data join session_data
on session_data.session_id = website_event.session_id on session_data.session_id = website_event.session_id
and session_data.website_id = website_event.website_id
where website_event.website_id = {{websiteId::uuid}} where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and website_event.created_at between {{startDate}} and {{endDate}}
${filterQuery} ${filterQuery}

View file

@ -38,7 +38,6 @@ async function relationalQuery(
${joinSessionQuery} ${joinSessionQuery}
join session_data join session_data
on session_data.session_id = website_event.session_id on session_data.session_id = website_event.session_id
and session_data.website_id = website_event.website_id
where website_event.website_id = {{websiteId::uuid}} where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and website_event.created_at between {{startDate}} and {{endDate}}
and session_data.data_key = {{propertyName}} and session_data.data_key = {{propertyName}}

View file

@ -37,7 +37,7 @@ async function relationalQuery(
): Promise<SessionExpandedMetricsData[]> { ): Promise<SessionExpandedMetricsData[]> {
const { type, limit = 500, offset = 0 } = parameters; const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type; let column = FILTER_COLUMNS[type] || type;
const { parseFilters, rawQuery, getTimestampDiffSQL } = prisma; const { parseFilters, rawQuery } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters( const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters(
{ {
...filters, ...filters,
@ -55,36 +55,20 @@ async function relationalQuery(
return rawQuery( return rawQuery(
` `
select select
name, ${column} x,
${includeCountry ? 'country,' : ''} count(distinct website_event.session_id) y
sum(t.c) as "pageviews",
count(distinct t.session_id) as "visitors",
count(distinct t.visit_id) as "visits",
sum(case when t.c = 1 then 1 else 0 end) as "bounces",
sum(${getTimestampDiffSQL('t.min_time', 't.max_time')}) as "totaltime"
from (
select
${column} name,
${includeCountry ? 'country,' : ''}
website_event.session_id,
website_event.visit_id,
count(*) as "c",
min(website_event.created_at) as "min_time",
max(website_event.created_at) as "max_time"
from website_event
${cohortQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
and website_event.event_type != 2
${filterQuery}
group by name, website_event.session_id, website_event.visit_id
${includeCountry ? ', country' : ''} ${includeCountry ? ', country' : ''}
) as t from website_event
group by name ${cohortQuery}
${includeCountry ? ', country' : ''} ${joinSessionQuery}
order by visitors desc, visits desc where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
and website_event.event_type != 2
${filterQuery}
group by 1
${includeCountry ? ', 3' : ''}
order by 2 desc
limit ${limit} limit ${limit}
offset ${offset} offset ${offset}
`, `,

View file

@ -44,7 +44,6 @@ async function relationalQuery(
from website_event from website_event
${cohortQuery} ${cohortQuery}
join session on website_event.session_id = session.session_id join session on website_event.session_id = session.session_id
and website_event.website_id = session.website_id
where website_event.website_id = {{websiteId::uuid}} where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}} and website_event.created_at between {{startDate}} and {{endDate}}
${filterQuery} ${filterQuery}

View file

@ -52,7 +52,6 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
from website_event from website_event
${cohortQuery} ${cohortQuery}
join session on session.session_id = website_event.session_id join session on session.session_id = website_event.session_id
and session.website_id = website_event.website_id
where website_event.website_id = {{websiteId::uuid}} where website_event.website_id = {{websiteId::uuid}}
${dateQuery} ${dateQuery}
${filterQuery} ${filterQuery}