mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-19 08:02:55 +00:00
feat: add support for range filters
This commit is contained in:
committed by
Rainer Killinger
parent
785813c3fb
commit
dcf7906f79
@@ -283,6 +283,53 @@ export interface ESTermFilter {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ESGenericRange<T> {
|
||||
/**
|
||||
* Greater than field
|
||||
*/
|
||||
gt?: T;
|
||||
|
||||
/**
|
||||
* Greater or equal than field
|
||||
*/
|
||||
gte?: T;
|
||||
|
||||
/**
|
||||
* Less than field
|
||||
*/
|
||||
lt?: T;
|
||||
|
||||
/**
|
||||
* Less or equal than field
|
||||
*/
|
||||
lte?: T;
|
||||
}
|
||||
|
||||
interface ESGenericRangeFilter<G, T extends ESGenericRange<G>> {
|
||||
/**
|
||||
* Range filter definition
|
||||
*/
|
||||
range: {
|
||||
[fieldName: string]: T;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ESDateRange extends ESGenericRange<string> {
|
||||
/**
|
||||
* Optional date format override
|
||||
*/
|
||||
format?: string;
|
||||
|
||||
/**
|
||||
* Optional timezone specifier
|
||||
*/
|
||||
time_zone?: string;
|
||||
}
|
||||
|
||||
export type ESNumericRangeFilter = ESGenericRangeFilter<number, ESGenericRange<number>>;
|
||||
export type ESDateRangeFilter = ESGenericRangeFilter<string, ESDateRange>;
|
||||
export type ESRangeFilter = ESNumericRangeFilter | ESDateRangeFilter;
|
||||
|
||||
/**
|
||||
* Checks if the parameter is of type ESTermsFilter
|
||||
* @param agg the value to check
|
||||
@@ -435,9 +482,9 @@ export interface ESFunctionScoreQueryFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* An elasticsearch ducet sort
|
||||
* An elasticsearch generic sort
|
||||
*/
|
||||
export interface ESDucetSort {
|
||||
export interface ESGenericSort {
|
||||
[field: string]: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +26,19 @@ import {
|
||||
SCThingsField,
|
||||
SCThingType,
|
||||
} from '@openstapps/core';
|
||||
import {ElasticsearchConfig, ScriptSort} from './common';
|
||||
import {
|
||||
ElasticsearchConfig,
|
||||
ESDateRange,
|
||||
ESDateRangeFilter, ESGenericRange, ESNumericRangeFilter,
|
||||
ESRangeFilter,
|
||||
ScriptSort,
|
||||
} from './common';
|
||||
import {
|
||||
ESBooleanFilter,
|
||||
ESBooleanFilterArguments,
|
||||
ESDucetSort,
|
||||
ESFunctionScoreQuery,
|
||||
ESFunctionScoreQueryFunction,
|
||||
ESGenericSort,
|
||||
ESGeoDistanceFilter,
|
||||
ESGeoDistanceFilterArguments,
|
||||
ESGeoDistanceSort,
|
||||
@@ -89,7 +95,8 @@ export function buildBooleanFilter(booleanFilter: SCSearchBooleanFilter): ESBool
|
||||
* Converts Array of Filters to elasticsearch query-syntax
|
||||
* @param filter A search filter for the retrieval of the data
|
||||
*/
|
||||
export function buildFilter(filter: SCSearchFilter): ESTermFilter | ESGeoDistanceFilter | ESBooleanFilter<unknown> {
|
||||
export function buildFilter(filter: SCSearchFilter):
|
||||
ESTermFilter | ESGeoDistanceFilter | ESBooleanFilter<unknown> | ESRangeFilter {
|
||||
|
||||
switch (filter.type) {
|
||||
case 'value':
|
||||
@@ -109,8 +116,7 @@ export function buildFilter(filter: SCSearchFilter): ESTermFilter | ESGeoDistanc
|
||||
};
|
||||
} = {};
|
||||
startRangeFilter[filter.arguments.fromField] = {
|
||||
lte: typeof filter.arguments.time !== 'undefined'
|
||||
? filter.arguments.time : 'now',
|
||||
lte: filter.arguments.time ?? 'now',
|
||||
};
|
||||
|
||||
const endRangeFilter: {
|
||||
@@ -122,8 +128,7 @@ export function buildFilter(filter: SCSearchFilter): ESTermFilter | ESGeoDistanc
|
||||
};
|
||||
} = {};
|
||||
endRangeFilter[filter.arguments.toField] = {
|
||||
gte: typeof filter.arguments.time !== 'undefined'
|
||||
? filter.arguments.time : 'now',
|
||||
gte: filter.arguments.time ?? 'now',
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -176,6 +181,42 @@ export function buildFilter(filter: SCSearchFilter): ESTermFilter | ESGeoDistanc
|
||||
return {
|
||||
bool: buildBooleanFilter(filter),
|
||||
};
|
||||
case 'numeric range':
|
||||
const numericRangeObject: ESGenericRange<number> = {};
|
||||
if (filter.arguments.bounds.lowerBound?.mode === 'exclusive') {
|
||||
numericRangeObject.gt = filter.arguments.bounds.lowerBound.limit;
|
||||
} else if (filter.arguments.bounds.lowerBound?.mode === 'inclusive') {
|
||||
numericRangeObject.gte = filter.arguments.bounds.lowerBound.limit;
|
||||
}
|
||||
if (filter.arguments.bounds.upperBound?.mode === 'exclusive') {
|
||||
numericRangeObject.lt = filter.arguments.bounds.upperBound.limit;
|
||||
} else if (filter.arguments.bounds.upperBound?.mode === 'inclusive') {
|
||||
numericRangeObject.lte = filter.arguments.bounds.upperBound.limit;
|
||||
}
|
||||
|
||||
const numericRangeFilter: ESNumericRangeFilter = {range: {}};
|
||||
numericRangeFilter.range[filter.arguments.field] = numericRangeObject;
|
||||
|
||||
return numericRangeFilter;
|
||||
case 'date range':
|
||||
const dateRangeObject: ESDateRange = {};
|
||||
if (filter.arguments.bounds.lowerBound?.mode === 'exclusive') {
|
||||
dateRangeObject.lt = filter.arguments.bounds.lowerBound.limit;
|
||||
} else if (filter.arguments.bounds.lowerBound?.mode === 'inclusive') {
|
||||
dateRangeObject.lte = filter.arguments.bounds.lowerBound.limit;
|
||||
}
|
||||
if (filter.arguments.bounds.upperBound?.mode === 'exclusive') {
|
||||
dateRangeObject.gt = filter.arguments.bounds.upperBound.limit;
|
||||
} else if (filter.arguments.bounds.upperBound?.mode === 'inclusive') {
|
||||
dateRangeObject.gte = filter.arguments.bounds.upperBound.limit;
|
||||
}
|
||||
dateRangeObject.format = filter.arguments.format;
|
||||
dateRangeObject.time_zone = filter.arguments.timeZone;
|
||||
|
||||
const dateRangeFilter: ESDateRangeFilter = {range: {}};
|
||||
dateRangeFilter.range[filter.arguments.field] = dateRangeObject;
|
||||
|
||||
return dateRangeFilter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,14 +444,19 @@ export function buildQuery(
|
||||
*/
|
||||
export function buildSort(
|
||||
sorts: SCSearchSort[],
|
||||
): Array<ESDucetSort | ESGeoDistanceSort | ScriptSort> {
|
||||
): Array<ESGenericSort | ESGeoDistanceSort | ScriptSort> {
|
||||
return sorts.map((sort) => {
|
||||
switch (sort.type) {
|
||||
case 'ducet':
|
||||
const ducetSort: ESDucetSort = {};
|
||||
ducetSort[`${sort.arguments.field}.sort`] = sort.order;
|
||||
case 'generic':
|
||||
const esGenericSort: ESGenericSort = {};
|
||||
esGenericSort[sort.arguments.field] = sort.order;
|
||||
|
||||
return ducetSort;
|
||||
return esGenericSort;
|
||||
case 'ducet':
|
||||
const esDucetSort: ESGenericSort = {};
|
||||
esDucetSort[`${sort.arguments.field}.sort`] = sort.order;
|
||||
|
||||
return esDucetSort;
|
||||
case 'distance':
|
||||
const args: ESGeoDistanceSortArguments = {
|
||||
mode: 'avg',
|
||||
|
||||
Reference in New Issue
Block a user