Change event search to use similar to clause
- enable more customized searches (and/or nesting)
This commit is contained in:
parent
73022c7b45
commit
b5022ac2c6
|
@ -52,9 +52,13 @@ export const paramDef = {
|
||||||
sinceDate: { type: 'integer', nullable: true },
|
sinceDate: { type: 'integer', nullable: true },
|
||||||
untilDate: { type: 'integer', nullable: true },
|
untilDate: { type: 'integer', nullable: true },
|
||||||
filters: {
|
filters: {
|
||||||
type: 'object',
|
type: 'array',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
description: 'mapping of string -> [string] that filters events based on metadata',
|
description: 'list of string -> [string] that filters events based on metadata. Each item in filters is applied as an AND',
|
||||||
|
prefixItems: [
|
||||||
|
{ type: 'string', description: 'The property of metadata to be filtered' },
|
||||||
|
{ type: 'array', items: { type: 'string', nullable: true, description: 'The values to match the metadata against. Each item in this array is applied as an OR. Include null to indicate match on missing metadata' } },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
sortBy: { type: 'string', nullable: true, default: 'startDate', enum: ['startDate', 'createdAt'] },
|
sortBy: { type: 'string', nullable: true, default: 'startDate', enum: ['startDate', 'createdAt'] },
|
||||||
},
|
},
|
||||||
|
@ -99,15 +103,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (ps.filters) {
|
if (ps.filters) {
|
||||||
const filters: Record<string, (string | null)[]> = ps.filters;
|
const filters: [string, (string | null)[]][] = ps.filters;
|
||||||
|
|
||||||
Object.keys(filters).forEach(f => {
|
filters.forEach(f => {
|
||||||
const matches = filters[f].filter(x => x !== null);
|
const filterKey = f[0];
|
||||||
|
const filterValues = f[1];
|
||||||
|
const matches = filterValues.filter(x => x !== null) as string[];
|
||||||
|
const hasNull = filterValues.length !== matches.length;
|
||||||
if (matches.length < 1) throw new ApiError(meta.errors.invalidParam);
|
if (matches.length < 1) throw new ApiError(meta.errors.invalidParam);
|
||||||
query.andWhere(new Brackets((qb) => {
|
query.andWhere(new Brackets((qb) => {
|
||||||
qb.where('event.metadata ->> :key IN (:...values)', { key: f, values: matches });
|
qb.where('event.metadata ->> :key SIMILAR TO :values', { key: filterKey, values: `%(${ matches.map(sqlLikeEscape).map(m => m.trim()).filter(m => m.length).join('|') })%` });
|
||||||
if (filters[f].filter(x => x === null).length > 0) {
|
if (hasNull) {
|
||||||
qb.orWhere('event.metadata ->> :key IS NULL', { key: f });
|
qb.orWhere('event.metadata ->> :key IS NULL', { key: filterKey });
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -492,7 +492,7 @@ export type Endpoints = {
|
||||||
title: string;
|
title: string;
|
||||||
start: number;
|
start: number;
|
||||||
end?: null | number;
|
end?: null | number;
|
||||||
metadata: Record<string, string[]>;
|
metadata: Record<string, string>;
|
||||||
}
|
}
|
||||||
}; res: { createdNote: Note }; };
|
}; res: { createdNote: Note }; };
|
||||||
'notes/delete': { req: { noteId: Note['id']; }; res: null; };
|
'notes/delete': { req: { noteId: Note['id']; }; res: null; };
|
||||||
|
@ -515,7 +515,7 @@ export type Endpoints = {
|
||||||
sinceDate?: number;
|
sinceDate?: number;
|
||||||
untilDate?: number;
|
untilDate?: number;
|
||||||
sortBy?: 'startDate' | 'craetedAt';
|
sortBy?: 'startDate' | 'craetedAt';
|
||||||
filters?: Record<string, string[]>;
|
filters?: [string, (string | null)[]][];
|
||||||
}; res: Note[]; };
|
}; res: Note[]; };
|
||||||
'notes/reactions': { req: { noteId: Note['id']; type?: string | null; limit?: number; }; res: NoteReaction[]; };
|
'notes/reactions': { req: { noteId: Note['id']; type?: string | null; limit?: number; }; res: NoteReaction[]; };
|
||||||
'notes/reactions/create': { req: { noteId: Note['id']; reaction: string; }; res: null; };
|
'notes/reactions/create': { req: { noteId: Note['id']; reaction: string; }; res: null; };
|
||||||
|
|
Loading…
Reference in New Issue