mirror of
https://github.com/kremalicious/umami.git
synced 2024-11-22 01:46:58 +01:00
Fixed search for postgresql.
This commit is contained in:
parent
e6aebf5104
commit
91efb7f1d0
@ -92,31 +92,31 @@ function getTimestampDiffQuery(field1: string, field2: string): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapFilter(column: string, filter: string, name: string, type = 'varchar') {
|
function mapFilter(column: string, op: string, name: string, type = 'varchar') {
|
||||||
switch (filter) {
|
switch (op) {
|
||||||
case OPERATORS.equals:
|
case OPERATORS.equals:
|
||||||
return `${column} = {{${name}::${type}}}`;
|
return `${column} = {{${name}::${type}}}`;
|
||||||
case OPERATORS.notEquals:
|
case OPERATORS.notEquals:
|
||||||
return `${column} != {{${name}::${type}}}`;
|
return `${column} != {{${name}::${type}}}`;
|
||||||
case OPERATORS.contains:
|
case OPERATORS.contains:
|
||||||
return `${column} like {{${name}::${type}}}`;
|
return `${column} ilike {{${name}::${type}}}`;
|
||||||
case OPERATORS.doesNotContain:
|
case OPERATORS.doesNotContain:
|
||||||
return `${column} not like {{${name}::${type}}}`;
|
return `${column} not ilike {{${name}::${type}}}`;
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilterQuery(filters: QueryFilters = {}, options: QueryOptions = {}): string {
|
function getFilterQuery(filters: QueryFilters = {}, options: QueryOptions = {}): string {
|
||||||
const query = Object.keys(filters).reduce((arr, name) => {
|
const query = Object.keys(filters).reduce((arr, key) => {
|
||||||
const value = filters[name];
|
const filter = filters[key];
|
||||||
const filter = value?.filter ?? OPERATORS.equals;
|
const op = filter?.op ?? OPERATORS.equals;
|
||||||
const column = value?.column ?? FILTER_COLUMNS[name] ?? options?.columns?.[name];
|
const column = filter?.column ?? FILTER_COLUMNS[key] ?? options?.columns?.[key];
|
||||||
|
|
||||||
if (value !== undefined && column !== undefined) {
|
if (filter !== undefined && column !== undefined) {
|
||||||
arr.push(`and ${mapFilter(column, filter, name)}`);
|
arr.push(`and ${mapFilter(column, op, key)}`);
|
||||||
|
|
||||||
if (name === 'referrer') {
|
if (key === 'referrer') {
|
||||||
arr.push(
|
arr.push(
|
||||||
'and (website_event.referrer_domain != {{websiteDomain}} or website_event.referrer_domain is null)',
|
'and (website_event.referrer_domain != {{websiteDomain}} or website_event.referrer_domain is null)',
|
||||||
);
|
);
|
||||||
@ -171,7 +171,10 @@ async function rawQuery(sql: string, data: object): Promise<any> {
|
|||||||
|
|
||||||
const query = sql?.replaceAll(/\{\{\s*(\w+)(::\w+)?\s*}}/g, (...args) => {
|
const query = sql?.replaceAll(/\{\{\s*(\w+)(::\w+)?\s*}}/g, (...args) => {
|
||||||
const [, name, type] = args;
|
const [, name, type] = args;
|
||||||
params.push(data[name]);
|
|
||||||
|
const value = data[name];
|
||||||
|
|
||||||
|
params.push(value);
|
||||||
|
|
||||||
return db === MYSQL ? '?' : `$${params.length}${type ?? ''}`;
|
return db === MYSQL ? '?' : `$${params.length}${type ?? ''}`;
|
||||||
});
|
});
|
||||||
|
@ -97,7 +97,7 @@ export default async (req: NextApiRequestCollect, res: NextApiResponse) => {
|
|||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
let [urlPath, urlQuery] = url?.split('?') || [];
|
let [urlPath, urlQuery] = url?.split('?') || [];
|
||||||
let [referrerPath, referrerQuery] = referrer?.split('?') || [];
|
let [referrerPath, referrerQuery] = referrer?.split('?') || [];
|
||||||
let referrerDomain;
|
let referrerDomain = '';
|
||||||
|
|
||||||
if (!urlPath) {
|
if (!urlPath) {
|
||||||
urlPath = '/';
|
urlPath = '/';
|
||||||
|
@ -3,7 +3,7 @@ import { badRequest, methodNotAllowed, ok, unauthorized } from 'next-basics';
|
|||||||
import { WebsiteMetric, NextApiRequestQueryBody } from 'lib/types';
|
import { WebsiteMetric, NextApiRequestQueryBody } from 'lib/types';
|
||||||
import { canViewWebsite } from 'lib/auth';
|
import { canViewWebsite } from 'lib/auth';
|
||||||
import { useAuth, useCors, useValidate } from 'lib/middleware';
|
import { useAuth, useCors, useValidate } from 'lib/middleware';
|
||||||
import { SESSION_COLUMNS, EVENT_COLUMNS, FILTER_COLUMNS } from 'lib/constants';
|
import { SESSION_COLUMNS, EVENT_COLUMNS, FILTER_COLUMNS, OPERATORS } from 'lib/constants';
|
||||||
import { getPageviewMetrics, getSessionMetrics } from 'queries';
|
import { getPageviewMetrics, getSessionMetrics } from 'queries';
|
||||||
import { parseDateRangeQuery } from 'lib/query';
|
import { parseDateRangeQuery } from 'lib/query';
|
||||||
import * as yup from 'yup';
|
import * as yup from 'yup';
|
||||||
@ -88,7 +88,7 @@ export default async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { startDate, endDate } = await parseDateRangeQuery(req);
|
const { startDate, endDate } = await parseDateRangeQuery(req);
|
||||||
|
const column = FILTER_COLUMNS[type] || type;
|
||||||
const filters = {
|
const filters = {
|
||||||
startDate,
|
startDate,
|
||||||
endDate,
|
endDate,
|
||||||
@ -104,19 +104,18 @@ export default async (
|
|||||||
city,
|
city,
|
||||||
language,
|
language,
|
||||||
event,
|
event,
|
||||||
search,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const column = FILTER_COLUMNS[type] || type;
|
if (search) {
|
||||||
|
filters[column] = {
|
||||||
|
column,
|
||||||
|
op: OPERATORS.contains,
|
||||||
|
value: '%' + search + '%',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (SESSION_COLUMNS.includes(type)) {
|
if (SESSION_COLUMNS.includes(type)) {
|
||||||
const data = await getSessionMetrics(
|
const data = await getSessionMetrics(websiteId, column, filters, limit, offset);
|
||||||
websiteId,
|
|
||||||
column,
|
|
||||||
{ ...filters, search },
|
|
||||||
limit,
|
|
||||||
offset,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (type === 'language') {
|
if (type === 'language') {
|
||||||
const combined = {};
|
const combined = {};
|
||||||
@ -138,13 +137,7 @@ export default async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (EVENT_COLUMNS.includes(type)) {
|
if (EVENT_COLUMNS.includes(type)) {
|
||||||
const data = await getPageviewMetrics(
|
const data = await getPageviewMetrics(websiteId, column, filters, limit, offset);
|
||||||
websiteId,
|
|
||||||
column,
|
|
||||||
{ ...filters, search },
|
|
||||||
limit,
|
|
||||||
offset,
|
|
||||||
);
|
|
||||||
|
|
||||||
return ok(res, data);
|
return ok(res, data);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import clickhouse from 'lib/clickhouse';
|
import clickhouse from 'lib/clickhouse';
|
||||||
import { runQuery, CLICKHOUSE, PRISMA } from 'lib/db';
|
import { runQuery, CLICKHOUSE, PRISMA } from 'lib/db';
|
||||||
import { EVENT_TYPE, SESSION_COLUMNS, OPERATORS } from 'lib/constants';
|
import { EVENT_TYPE, SESSION_COLUMNS } from 'lib/constants';
|
||||||
import { QueryFilters } from 'lib/types';
|
import { QueryFilters } from 'lib/types';
|
||||||
|
|
||||||
export async function getPageviewMetrics(
|
export async function getPageviewMetrics(
|
||||||
@ -27,6 +27,7 @@ async function relationalQuery(
|
|||||||
offset: number = 0,
|
offset: number = 0,
|
||||||
) {
|
) {
|
||||||
const { rawQuery, parseFilters } = prisma;
|
const { rawQuery, parseFilters } = prisma;
|
||||||
|
|
||||||
const { filterQuery, joinSession, params } = await parseFilters(
|
const { filterQuery, joinSession, params } = await parseFilters(
|
||||||
websiteId,
|
websiteId,
|
||||||
{
|
{
|
||||||
@ -69,16 +70,9 @@ async function clickhouseQuery(
|
|||||||
offset: number = 0,
|
offset: number = 0,
|
||||||
): Promise<{ x: string; y: number }[]> {
|
): Promise<{ x: string; y: number }[]> {
|
||||||
const { rawQuery, parseFilters } = clickhouse;
|
const { rawQuery, parseFilters } = clickhouse;
|
||||||
|
|
||||||
const { filterQuery, params } = await parseFilters(websiteId, {
|
const { filterQuery, params } = await parseFilters(websiteId, {
|
||||||
...filters,
|
...filters,
|
||||||
...(filters.search && {
|
|
||||||
[column]: {
|
|
||||||
value: filters.search,
|
|
||||||
filter: OPERATORS.contains,
|
|
||||||
column,
|
|
||||||
name: column,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
eventType: column === 'event_name' ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView,
|
eventType: column === 'event_name' ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user