implement exclude bounces feature

This commit is contained in:
Francis Cao
2026-01-30 00:12:13 -08:00
parent 4a3190b2da
commit ee698b636a
21 changed files with 189 additions and 69 deletions
+8 -5
View File
@@ -41,10 +41,11 @@ async function relationalQuery(
filters: QueryFilters,
): Promise<ChannelExpandedMetricsData[]> {
const { rawQuery, parseFilters, getTimestampDiffSQL } = prisma;
const { queryParams, filterQuery, joinSessionQuery, cohortQuery, dateQuery } = parseFilters({
...filters,
websiteId,
});
const { queryParams, filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, dateQuery } =
parseFilters({
...filters,
websiteId,
});
return rawQuery(
`
@@ -64,6 +65,7 @@ async function relationalQuery(
max(website_event.created_at) max_time
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.event_type != 2
@@ -119,7 +121,7 @@ async function clickhouseQuery(
filters: QueryFilters,
): Promise<ChannelExpandedMetricsData[]> {
const { rawQuery, parseFilters } = clickhouse;
const { queryParams, filterQuery, cohortQuery } = parseFilters({
const { queryParams, filterQuery, cohortQuery, excludeBounceQuery } = parseFilters({
...filters,
websiteId,
});
@@ -166,6 +168,7 @@ async function clickhouseQuery(
max(created_at) max_time
from website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
+8 -5
View File
@@ -22,10 +22,11 @@ export async function getChannelMetrics(...args: [websiteId: string, filters?: Q
async function relationalQuery(websiteId: string, filters: QueryFilters) {
const { rawQuery, parseFilters } = prisma;
const { queryParams, filterQuery, joinSessionQuery, cohortQuery, dateQuery } = parseFilters({
...filters,
websiteId,
});
const { queryParams, filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, dateQuery } =
parseFilters({
...filters,
websiteId,
});
return rawQuery(
`
@@ -41,6 +42,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
website_event.session_id
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.event_type != 2
@@ -81,7 +83,7 @@ async function clickhouseQuery(
filters: QueryFilters,
): Promise<{ x: string; y: number }[]> {
const { rawQuery, parseFilters } = clickhouse;
const { queryParams, filterQuery, cohortQuery, dateQuery } = parseFilters({
const { queryParams, filterQuery, cohortQuery, excludeBounceQuery, dateQuery } = parseFilters({
...filters,
websiteId,
});
@@ -116,6 +118,7 @@ async function clickhouseQuery(
count(distinct session_id) y
from website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and event_type != 2
${dateQuery}
+10 -5
View File
@@ -28,10 +28,11 @@ async function relationalQuery(
filters: QueryFilters,
): Promise<WebsiteStatsData[]> {
const { getTimestampDiffSQL, parseFilters, rawQuery } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
const { filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, queryParams } =
parseFilters({
...filters,
websiteId,
});
return rawQuery(
`
@@ -50,12 +51,14 @@ async function relationalQuery(
max(website_event.created_at) as "max_time"
from website_event
${cohortQuery}
${excludeBounceQuery}
${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 1, 2
) as t
`,
queryParams,
@@ -68,7 +71,7 @@ async function clickhouseQuery(
filters: QueryFilters,
): Promise<WebsiteStatsData[]> {
const { rawQuery, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
@@ -92,6 +95,7 @@ async function clickhouseQuery(
max(created_at) max_time
from website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
@@ -115,6 +119,7 @@ async function clickhouseQuery(
max(max_time) max_time
from website_event_stats_hourly "website_event"
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
+11 -5
View File
@@ -16,10 +16,11 @@ export async function getWeeklyTraffic(...args: [websiteId: string, filters: Que
async function relationalQuery(websiteId: string, filters: QueryFilters) {
const { timezone = 'utc' } = filters;
const { rawQuery, getDateWeeklySQL, parseFilters } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
const { filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, queryParams } =
parseFilters({
...filters,
websiteId,
});
return rawQuery(
`
@@ -28,6 +29,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
count(distinct website_event.session_id) as value
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
@@ -43,7 +45,10 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
async function clickhouseQuery(websiteId: string, filters: QueryFilters) {
const { timezone = 'utc' } = filters;
const { rawQuery, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = await parseFilters({ ...filters, websiteId });
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = await parseFilters({
...filters,
websiteId,
});
let sql = '';
@@ -67,6 +72,7 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters) {
count(distinct session_id) as value
from website_event_stats_hourly website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
${filterQuery}
@@ -38,13 +38,14 @@ async function relationalQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { rawQuery, parseFilters, getTimestampDiffSQL } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters(
{
...filters,
websiteId,
},
{ joinSession: SESSION_COLUMNS.includes(type) },
);
const { filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, queryParams } =
parseFilters(
{
...filters,
websiteId,
},
{ joinSession: SESSION_COLUMNS.includes(type) },
);
let entryExitQuery = '';
let excludeDomain = '';
@@ -94,6 +95,7 @@ async function relationalQuery(
max(website_event.created_at) as "max_time"
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
${entryExitQuery}
where website_event.website_id = {{websiteId::uuid}}
@@ -122,7 +124,7 @@ async function clickhouseQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { rawQuery, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
@@ -171,6 +173,7 @@ async function clickhouseQuery(
max(created_at) max_time
from website_event
${cohortQuery}
${excludeBounceQuery}
${entryExitQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
@@ -34,13 +34,14 @@ async function relationalQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { rawQuery, parseFilters } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters(
{
...filters,
websiteId,
},
{ joinSession: SESSION_COLUMNS.includes(type) },
);
const { filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, queryParams } =
parseFilters(
{
...filters,
websiteId,
},
{ joinSession: SESSION_COLUMNS.includes(type) },
);
let entryExitQuery = '';
let excludeDomain = '';
@@ -75,6 +76,7 @@ async function relationalQuery(
count(distinct website_event.session_id) as y
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
${entryExitQuery}
where website_event.website_id = {{websiteId::uuid}}
@@ -100,7 +102,7 @@ async function clickhouseQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { rawQuery, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
@@ -135,6 +137,7 @@ async function clickhouseQuery(
uniq(website_event.session_id) as y
from website_event
${cohortQuery}
${excludeBounceQuery}
${entryExitQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
@@ -174,6 +177,7 @@ async function clickhouseQuery(
${columnQuery} as t
from website_event_stats_hourly as website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
@@ -16,10 +16,11 @@ export async function getPageviewStats(...args: [websiteId: string, filters: Que
async function relationalQuery(websiteId: string, filters: QueryFilters) {
const { timezone = 'utc', unit = 'day' } = filters;
const { getDateSQL, parseFilters, rawQuery } = prisma;
const { filterQuery, cohortQuery, joinSessionQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
const { filterQuery, cohortQuery, excludeBounceQuery, joinSessionQuery, queryParams } =
parseFilters({
...filters,
websiteId,
});
return rawQuery(
`
@@ -28,6 +29,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
count(*) y
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
@@ -47,7 +49,7 @@ async function clickhouseQuery(
): Promise<{ x: string; y: number }[]> {
const { timezone = 'UTC', unit = 'day' } = filters;
const { parseFilters, rawQuery, getDateSQL } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
@@ -65,6 +67,7 @@ async function clickhouseQuery(
count(*) as y
from website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
@@ -84,6 +87,7 @@ async function clickhouseQuery(
sum(views) as y
from website_event_stats_hourly as website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
@@ -38,15 +38,16 @@ async function relationalQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { parseFilters, rawQuery, getTimestampDiffSQL } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters(
{
...filters,
websiteId,
},
{
joinSession: SESSION_COLUMNS.includes(type),
},
);
const { filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, queryParams } =
parseFilters(
{
...filters,
websiteId,
},
{
joinSession: SESSION_COLUMNS.includes(type),
},
);
const includeCountry = column === 'city' || column === 'region';
if (type === 'language') {
@@ -74,6 +75,7 @@ async function relationalQuery(
max(website_event.created_at) as "max_time"
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
@@ -102,7 +104,7 @@ async function clickhouseQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { parseFilters, rawQuery } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
@@ -133,6 +135,7 @@ async function clickhouseQuery(
max(created_at) max_time
from website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
+14 -10
View File
@@ -29,15 +29,16 @@ async function relationalQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { parseFilters, rawQuery } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters(
{
...filters,
websiteId,
},
{
joinSession: SESSION_COLUMNS.includes(type),
},
);
const { filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, queryParams } =
parseFilters(
{
...filters,
websiteId,
},
{
joinSession: SESSION_COLUMNS.includes(type),
},
);
const includeCountry = column === 'city' || column === 'region';
if (type === 'language') {
@@ -52,6 +53,7 @@ async function relationalQuery(
${includeCountry ? ', country' : ''}
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
@@ -76,7 +78,7 @@ async function clickhouseQuery(
const { type, limit = 500, offset = 0 } = parameters;
let column = FILTER_COLUMNS[type] || type;
const { parseFilters, rawQuery } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
@@ -96,6 +98,7 @@ async function clickhouseQuery(
${includeCountry ? ', country' : ''}
from website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
@@ -114,6 +117,7 @@ async function clickhouseQuery(
${includeCountry ? ', country' : ''}
from website_event_stats_hourly as website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
+9 -5
View File
@@ -16,10 +16,11 @@ export async function getSessionStats(...args: [websiteId: string, filters: Quer
async function relationalQuery(websiteId: string, filters: QueryFilters) {
const { timezone = 'utc', unit = 'day' } = filters;
const { getDateSQL, parseFilters, rawQuery } = prisma;
const { filterQuery, joinSessionQuery, cohortQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
const { filterQuery, joinSessionQuery, cohortQuery, excludeBounceQuery, queryParams } =
parseFilters({
...filters,
websiteId,
});
return rawQuery(
`
@@ -28,6 +29,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
count(distinct website_event.session_id) y
from website_event
${cohortQuery}
${excludeBounceQuery}
${joinSessionQuery}
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
@@ -47,7 +49,7 @@ async function clickhouseQuery(
): Promise<{ x: string; y: number }[]> {
const { timezone = 'UTC', unit = 'day' } = filters;
const { parseFilters, rawQuery, getDateSQL } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
const { filterQuery, cohortQuery, excludeBounceQuery, queryParams } = parseFilters({
...filters,
websiteId,
});
@@ -65,6 +67,7 @@ async function clickhouseQuery(
count(distinct session_id) as y
from website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2
@@ -84,6 +87,7 @@ async function clickhouseQuery(
uniq(session_id) as y
from website_event_stats_hourly as website_event
${cohortQuery}
${excludeBounceQuery}
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type != 2