mirror of
https://github.com/kremalicious/umami.git
synced 2024-06-28 16:57:52 +02:00
Added "columns" to query options. Added events count to event data metrics.
This commit is contained in:
parent
9d86385f5c
commit
7da7f58cbe
|
@ -28,6 +28,11 @@ export function EventDataMetricsBar({ websiteId }) {
|
|||
<MetricsBar isLoading={isLoading} isFetched={isFetched} error={error}>
|
||||
{!error && isFetched && (
|
||||
<>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.events)}
|
||||
value={data?.events}
|
||||
/>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.fields)}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ClickHouse } from 'clickhouse';
|
|||
import dateFormat from 'dateformat';
|
||||
import debug from 'debug';
|
||||
import { CLICKHOUSE } from 'lib/db';
|
||||
import { QueryFilters } from './types';
|
||||
import { QueryFilters, QueryOptions } from './types';
|
||||
import { FILTER_COLUMNS } from './constants';
|
||||
import { loadWebsite } from './load';
|
||||
import { maxDate } from './date';
|
||||
|
@ -63,10 +63,10 @@ function getDateFormat(date) {
|
|||
return `'${dateFormat(date, 'UTC:yyyy-mm-dd HH:MM:ss')}'`;
|
||||
}
|
||||
|
||||
function getFilterQuery(filters = {}) {
|
||||
function getFilterQuery(filters: QueryFilters = {}, options: QueryOptions = {}) {
|
||||
const query = Object.keys(filters).reduce((arr, key) => {
|
||||
const filter = filters[key];
|
||||
const column = FILTER_COLUMNS[key];
|
||||
const column = FILTER_COLUMNS[key] ?? options?.columns?.[key];
|
||||
|
||||
if (filter !== undefined && column) {
|
||||
arr.push(`and ${column} = {${key}:String}`);
|
||||
|
@ -85,11 +85,12 @@ function getFilterQuery(filters = {}) {
|
|||
async function parseFilters(
|
||||
websiteId: string,
|
||||
filters: QueryFilters & { [key: string]: any } = {},
|
||||
options?: QueryOptions,
|
||||
) {
|
||||
const website = await loadWebsite(websiteId);
|
||||
|
||||
return {
|
||||
filterQuery: getFilterQuery(filters),
|
||||
filterQuery: getFilterQuery(filters, options),
|
||||
params: {
|
||||
...filters,
|
||||
websiteId,
|
||||
|
|
|
@ -67,10 +67,10 @@ function getTimestampIntervalQuery(field: string): string {
|
|||
}
|
||||
}
|
||||
|
||||
function getFilterQuery(filters = {}): string {
|
||||
function getFilterQuery(filters: QueryFilters = {}, options: QueryOptions = {}): string {
|
||||
const query = Object.keys(filters).reduce((arr, key) => {
|
||||
const filter = filters[key];
|
||||
const column = FILTER_COLUMNS[key];
|
||||
const column = FILTER_COLUMNS[key] ?? options?.columns?.[key];
|
||||
|
||||
if (filter !== undefined && column) {
|
||||
arr.push(`and ${column}={{${key}}}`);
|
||||
|
@ -100,7 +100,7 @@ async function parseFilters(
|
|||
options?.joinSession || Object.keys(filters).find(key => SESSION_COLUMNS.includes(key))
|
||||
? `inner join session on website_event.session_id = session.session_id`
|
||||
: '',
|
||||
filterQuery: getFilterQuery(filters),
|
||||
filterQuery: getFilterQuery(filters, options),
|
||||
params: {
|
||||
...filters,
|
||||
websiteId,
|
||||
|
|
12
lib/types.ts
12
lib/types.ts
|
@ -80,15 +80,15 @@ export interface WebsiteEventMetric {
|
|||
}
|
||||
|
||||
export interface WebsiteEventDataStats {
|
||||
field: string;
|
||||
type: number;
|
||||
fieldName: string;
|
||||
dataType: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface WebsiteEventDataFields {
|
||||
field: string;
|
||||
type: number;
|
||||
value?: string;
|
||||
fieldName: string;
|
||||
dataType: number;
|
||||
fieldValue?: string;
|
||||
total: number;
|
||||
}
|
||||
|
||||
|
@ -152,5 +152,5 @@ export interface QueryFilters {
|
|||
|
||||
export interface QueryOptions {
|
||||
joinSession?: boolean;
|
||||
ignoreFilters?: string[];
|
||||
columns?: { [key: string]: string };
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ export interface EventDataFieldsRequestBody {
|
|||
startDate: string;
|
||||
endDate: string;
|
||||
};
|
||||
field?: string;
|
||||
}
|
||||
|
||||
export default async (
|
||||
|
@ -27,7 +28,10 @@ export default async (
|
|||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const data = await getEventDataFields(websiteId, new Date(+startAt), new Date(+endAt), field);
|
||||
const startDate = new Date(+startAt);
|
||||
const endDate = new Date(+endAt);
|
||||
|
||||
const data = await getEventDataFields(websiteId, { startDate, endDate, field });
|
||||
|
||||
return ok(res, data);
|
||||
}
|
||||
|
|
|
@ -32,16 +32,18 @@ export default async (
|
|||
const endDate = new Date(+endAt);
|
||||
|
||||
const results = await getEventDataFields(websiteId, { startDate, endDate });
|
||||
const events = new Set();
|
||||
|
||||
const data = results.reduce(
|
||||
(obj, row) => {
|
||||
events.add(row.fieldName);
|
||||
obj.records += Number(row.total);
|
||||
return obj;
|
||||
},
|
||||
{ fields: results.length, records: 0 },
|
||||
);
|
||||
|
||||
return ok(res, data);
|
||||
return ok(res, { ...data, events: events.size });
|
||||
}
|
||||
|
||||
return methodNotAllowed(res);
|
||||
|
|
|
@ -14,39 +14,23 @@ export async function getEventDataFields(
|
|||
|
||||
async function relationalQuery(websiteId: string, filters: QueryFilters & { field?: string }) {
|
||||
const { rawQuery, parseFilters } = prisma;
|
||||
const { field } = filters;
|
||||
const { params } = await parseFilters(websiteId, filters);
|
||||
|
||||
if (field) {
|
||||
return rawQuery(
|
||||
`
|
||||
select
|
||||
event_key as field,
|
||||
string_value as value,
|
||||
count(*) as total
|
||||
from event_data
|
||||
where website_id = {{websiteId::uuid}}
|
||||
and event_key = {{field}}
|
||||
and created_at between {{startDate}} and {{endDate}}
|
||||
group by event_key, string_value
|
||||
order by 3 desc, 2 desc, 1 asc
|
||||
limit 100
|
||||
`,
|
||||
params,
|
||||
);
|
||||
}
|
||||
const { filterQuery, params } = await parseFilters(websiteId, filters, {
|
||||
columns: { field: 'event_key' },
|
||||
});
|
||||
|
||||
return rawQuery(
|
||||
`
|
||||
select
|
||||
event_key as field,
|
||||
data_type as type,
|
||||
event_key as fieldName,
|
||||
data_type as dataType,
|
||||
string_value as fieldValue,
|
||||
count(*) as total
|
||||
from event_data
|
||||
where website_id = {{websiteId::uuid}}
|
||||
and created_at between {{startDate}} and {{endDate}}
|
||||
group by event_key, data_type
|
||||
order by 3 desc, 2 asc, 1 asc
|
||||
${filterQuery}
|
||||
group by event_key, data_type, string_value
|
||||
order by 3 desc, 2 desc, 1 asc
|
||||
limit 100
|
||||
`,
|
||||
params,
|
||||
|
@ -55,39 +39,23 @@ async function relationalQuery(websiteId: string, filters: QueryFilters & { fiel
|
|||
|
||||
async function clickhouseQuery(websiteId: string, filters: QueryFilters & { field?: string }) {
|
||||
const { rawQuery, parseFilters } = clickhouse;
|
||||
const { field } = filters;
|
||||
const { params } = await parseFilters(websiteId, filters);
|
||||
|
||||
if (field) {
|
||||
return rawQuery(
|
||||
`
|
||||
select
|
||||
event_key as field,
|
||||
string_value as value,
|
||||
count(*) as total
|
||||
from event_data
|
||||
where website_id = {websiteId:UUID}
|
||||
and event_key = {field:String}
|
||||
and created_at between {startDate:DateTime} and {endDate:DateTime}
|
||||
group by event_key, string_value
|
||||
order by 3 desc, 2 desc, 1 asc
|
||||
limit 100
|
||||
`,
|
||||
params,
|
||||
);
|
||||
}
|
||||
const { filterQuery, params } = await parseFilters(websiteId, filters, {
|
||||
columns: { field: 'event_key' },
|
||||
});
|
||||
|
||||
return rawQuery(
|
||||
`
|
||||
select
|
||||
event_key as field,
|
||||
data_type as type,
|
||||
event_key as fieldName,
|
||||
data_type as dataType,
|
||||
string_value as fieldValue,
|
||||
count(*) as total
|
||||
from event_data
|
||||
where website_id = {websiteId:UUID}
|
||||
and created_at between {startDate:DateTime} and {endDate:DateTime}
|
||||
group by event_key, data_type
|
||||
order by 3 desc, 2 asc, 1 asc
|
||||
${filterQuery}
|
||||
group by event_key, data_type, string_value
|
||||
order by 3 desc, 2 desc, 1 asc
|
||||
limit 100
|
||||
`,
|
||||
params,
|
||||
|
|
Loading…
Reference in New Issue
Block a user