feat: separate mongoQuery & add mongo filter

This commit is contained in:
minkik 2023-05-19 14:10:53 +09:00 committed by Joseph Lee
parent 4c57ab1388
commit b5b689b156
15 changed files with 858 additions and 710 deletions

View file

@ -1,5 +1,5 @@
import clickhouse from 'lib/clickhouse';
import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
import { CLICKHOUSE, MONGODB, PRISMA, runQuery } from 'lib/db';
import prisma from 'lib/prisma';
import { EVENT_TYPE } from 'lib/constants';
import { loadWebsite } from 'lib/query';
@ -20,6 +20,7 @@ export async function getPageviewStats(
) {
return runQuery({
[PRISMA]: () => relationalQuery(...args),
[MONGODB]: () => mongodbQuery(...args),
[CLICKHOUSE]: () => clickhouseQuery(...args),
});
}
@ -45,126 +46,14 @@ async function relationalQuery(
filters = {},
sessionKey = 'session_id',
} = criteria;
const { getDatabaseType, toUuid, getDateQuery, parseFilters, rawQuery, client } = prisma;
const db = getDatabaseType();
const { toUuid, getDateQuery, parseFilters, rawQuery } = prisma;
const website = await loadWebsite(websiteId);
const resetDate = new Date(website?.resetAt || website?.createdAt);
const params: any = [websiteId, resetDate, startDate, endDate];
const { filterQuery, joinSession } = parseFilters(filters, params);
let sessionInclude = '';
let sessionGroupAggregation: any = { $match: {} };
let sessionProjectAggregation: any = { $match: {} };
if (count !== '*') {
sessionInclude = 'session_id : 1';
sessionGroupAggregation = {
$group: {
_id: {
t: '$t',
session_id: '$session_id',
},
},
};
sessionProjectAggregation = {
$project: {
t: '$_id.t',
},
};
}
if (db === 'mongodb') {
return await client.websiteEvent.aggregateRaw({
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: ['$event_type', EVENT_TYPE.pageView],
},
{
$eq: ['$website_id', websiteId],
},
{
$gte: [
'$created_at',
{
$dateFromString: {
dateString: resetDate.toISOString(),
},
},
],
},
{
$gte: [
'$created_at',
{
$dateFromString: {
dateString: startDate.toISOString(),
},
},
],
},
{
$lte: [
'$created_at',
{
$dateFromString: {
dateString: endDate.toISOString(),
},
},
],
},
],
},
},
},
{
$project: {
t: {
$dateTrunc: {
date: '$created_at',
unit: unit,
},
},
sessionInclude,
},
},
sessionGroupAggregation,
sessionProjectAggregation,
{
$group: {
_id: {
t: '$t',
session_id: '$session_id',
},
y: {
$sum: 1,
},
},
},
{
$project: {
x: {
$dateToString: {
date: '$_id.t',
format: getDateQuery('', unit, timezone),
timezone: timezone,
},
},
y: 1,
_id: 0,
},
},
{
$sort: {
x: 1,
},
},
],
});
} else {
return rawQuery(
`select ${getDateQuery('website_event.created_at', unit, timezone)} x,
return rawQuery(
`select ${getDateQuery('website_event.created_at', unit, timezone)} x,
count(${count !== '*' ? `${count}${sessionKey}` : count}) y
from website_event
${joinSession}
@ -174,9 +63,8 @@ async function relationalQuery(
and event_type = ${EVENT_TYPE.pageView}
${filterQuery}
group by 1`,
params,
);
}
params,
);
}
async function clickhouseQuery(
@ -231,3 +119,149 @@ async function clickhouseQuery(
params,
);
}
async function mongodbQuery(
websiteId: string,
criteria: {
startDate: Date;
endDate: Date;
timezone?: string;
unit?: string;
count?: string;
filters: object;
sessionKey?: string;
},
) {
const {
startDate,
endDate,
timezone = 'utc',
unit = 'day',
count = '*',
filters = {},
} = criteria;
const { getDateQuery, client, parseMongoFilter } = prisma;
const website = await loadWebsite(websiteId);
const resetDate = new Date(website?.resetAt || website?.createdAt);
const mongoFilter = parseMongoFilter(filters);
let sessionInclude = '';
let sessionGroupAggregation: any = { $match: {} };
const sessionLookUpAggregation: any = {
$lookup: {
from: 'session',
foreignField: '_id',
localField: 'session_id',
as: 'session',
},
};
let sessionProjectAggregation: any = { $match: {} };
if (count !== '*') {
sessionInclude = 'session_id : 1';
sessionGroupAggregation = {
$group: {
_id: {
t: '$t',
session_id: '$session_id',
},
},
};
sessionProjectAggregation = {
$project: {
t: '$_id.t',
},
};
}
return await client.websiteEvent.aggregateRaw({
pipeline: [
sessionLookUpAggregation,
mongoFilter,
{
$match: {
$expr: {
$and: [
{
$eq: ['$event_type', EVENT_TYPE.pageView],
},
{
$eq: ['$website_id', websiteId],
},
{
$gte: [
'$created_at',
{
$dateFromString: {
dateString: resetDate.toISOString(),
},
},
],
},
{
$gte: [
'$created_at',
{
$dateFromString: {
dateString: startDate.toISOString(),
},
},
],
},
{
$lte: [
'$created_at',
{
$dateFromString: {
dateString: endDate.toISOString(),
},
},
],
},
],
},
},
},
{
$project: {
t: {
$dateTrunc: {
date: '$created_at',
unit: unit,
},
},
sessionInclude,
},
},
sessionGroupAggregation,
sessionProjectAggregation,
{
$group: {
_id: {
t: '$t',
session_id: '$session_id',
},
y: {
$sum: 1,
},
},
},
{
$project: {
x: {
$dateToString: {
date: '$_id.t',
format: getDateQuery('', unit, timezone),
timezone: timezone,
},
},
y: 1,
_id: 0,
},
},
{
$sort: {
x: 1,
},
},
],
});
}