mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-20 08:33:11 +00:00
refactor: simplify geo queries
This commit is contained in:
@@ -34,7 +34,7 @@ import {
|
||||
ESFunctionScoreQuery,
|
||||
ESFunctionScoreQueryFunction,
|
||||
ESGenericRange,
|
||||
ESGenericSort,
|
||||
ESGenericSort, ESGeoBoundingBoxFilter,
|
||||
ESGeoDistanceFilter,
|
||||
ESGeoDistanceFilterArguments,
|
||||
ESGeoDistanceSort,
|
||||
@@ -96,7 +96,7 @@ export function buildBooleanFilter(booleanFilter: SCSearchBooleanFilter): ESBool
|
||||
* @param filter A search filter for the retrieval of the data
|
||||
*/
|
||||
export function buildFilter(filter: SCSearchFilter):
|
||||
ESTermFilter | ESGeoDistanceFilter | ESGeoShapeFilter | ESBooleanFilter<unknown> | ESRangeFilter {
|
||||
ESTermFilter | ESGeoDistanceFilter | ESBooleanFilter<ESGeoShapeFilter | ESGeoBoundingBoxFilter> | ESGeoShapeFilter | ESBooleanFilter<unknown> | ESRangeFilter {
|
||||
|
||||
switch (filter.type) {
|
||||
case 'value':
|
||||
@@ -125,10 +125,10 @@ export function buildFilter(filter: SCSearchFilter):
|
||||
case 'distance':
|
||||
const geoObject: ESGeoDistanceFilterArguments = {
|
||||
distance: `${filter.arguments.distance}m`,
|
||||
};
|
||||
geoObject[filter.arguments.field] = {
|
||||
lat: filter.arguments.position[1],
|
||||
lon: filter.arguments.position[0],
|
||||
[`${filter.arguments.field}.point.coordinates`]: {
|
||||
lat: filter.arguments.position[1],
|
||||
lon: filter.arguments.position[0],
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -179,12 +179,50 @@ export function buildFilter(filter: SCSearchFilter):
|
||||
|
||||
return dateRangeFilter;
|
||||
case 'geo':
|
||||
return {
|
||||
[filter.arguments.field]: {
|
||||
shape: filter.arguments.shape,
|
||||
relation: filter.arguments.spatialRelation,
|
||||
// TODO: on ES upgrade, use just geo_shape filters
|
||||
const geoShapeFilter: ESGeoShapeFilter = {
|
||||
geo_shape: {
|
||||
/**
|
||||
* https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html#_ignore_unmapped_3
|
||||
*/
|
||||
// tslint:disable-next-line:ban-ts-ignore
|
||||
// @ts-ignore unfortunately, typescript is stupid and won't allow me to map this to an actual type.
|
||||
ignore_unmapped: true,
|
||||
[`${filter.arguments.field}.polygon`]: {
|
||||
shape: filter.arguments.shape,
|
||||
relation: filter.arguments.spatialRelation,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if ((typeof filter.arguments.spatialRelation === 'undefined' || filter.arguments.spatialRelation === 'intersects')
|
||||
&& filter.arguments.shape.type === 'envelope'
|
||||
) {
|
||||
return {
|
||||
bool: {
|
||||
minimum_should_match: 1,
|
||||
should: [
|
||||
geoShapeFilter,
|
||||
{
|
||||
geo_bounding_box: {
|
||||
/**
|
||||
* https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html#_ignore_unmapped_3
|
||||
*/
|
||||
// tslint:disable-next-line:ban-ts-ignore
|
||||
// @ts-ignore unfortunately, typescript is stupid and won't allow me to map this to an actual type.
|
||||
ignore_unmapped: true,
|
||||
[`${filter.arguments.field}.point.coordinates`]: {
|
||||
bottom_right: filter.arguments.shape.coordinates[0],
|
||||
top_left: filter.arguments.shape.coordinates[1],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return geoShapeFilter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +433,7 @@ export function buildSort(
|
||||
unit: 'm',
|
||||
};
|
||||
|
||||
args[sort.arguments.field] = {
|
||||
args[`${sort.arguments.field}.point.coordinates`] = {
|
||||
lat: sort.arguments.position[1],
|
||||
lon: sort.arguments.position[0],
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ import {SCThing, SCThingType} from '@openstapps/core';
|
||||
// tslint:disable-next-line:no-implicit-dependencies
|
||||
import {NameList} from 'elasticsearch';
|
||||
// tslint:disable-next-line:no-implicit-dependencies
|
||||
import {Polygon} from 'geojson';
|
||||
import {Polygon, Position} from 'geojson';
|
||||
|
||||
/**
|
||||
* An elasticsearch aggregation bucket
|
||||
@@ -366,23 +366,67 @@ export interface ESGeoDistanceFilter {
|
||||
geo_distance: ESGeoDistanceFilterArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* A rectangular geo shape, representing the top-left and bottom-right corners
|
||||
*
|
||||
* This is an extension of the Geojson type
|
||||
* http://geojson.org/geojson-spec.html
|
||||
*/
|
||||
export interface ESEnvelope {
|
||||
/**
|
||||
* The top-left and bottom-right corners of the bounding box
|
||||
*/
|
||||
coordinates: [Position, Position];
|
||||
|
||||
/**
|
||||
* The type of the geometry
|
||||
*/
|
||||
type: 'envelope';
|
||||
}
|
||||
|
||||
/**
|
||||
* An Elasticsearch geo bounding box filter
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-bounding-box-query.html
|
||||
*/
|
||||
export interface ESGeoBoundingBoxFilter {
|
||||
/**
|
||||
* An Elasticsearch geo bounding box filter
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-bounding-box-query.html
|
||||
*/
|
||||
geo_bounding_box: {
|
||||
[fieldName: string]: {
|
||||
/**
|
||||
* Geo Shape
|
||||
*/
|
||||
bottom_right: Position;
|
||||
|
||||
/**
|
||||
* Geo Shape
|
||||
*/
|
||||
top_left: Position;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* An Elasticsearch geo shape filter
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html
|
||||
*/
|
||||
export interface ESGeoShapeFilter {
|
||||
[fieldName: string]: {
|
||||
/**
|
||||
* Relation of the two shapes
|
||||
*
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html#_spatial_relations
|
||||
*/
|
||||
relation?: 'intersects' | 'disjoint' | 'within' | 'contains';
|
||||
geo_shape: {
|
||||
[fieldName: string]: {
|
||||
/**
|
||||
* Relation of the two shapes
|
||||
*
|
||||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-geo-shape-query.html#_spatial_relations
|
||||
*/
|
||||
relation?: 'intersects' | 'disjoint' | 'within' | 'contains';
|
||||
|
||||
/**
|
||||
* Geo Shape
|
||||
*/
|
||||
shape: Polygon;
|
||||
/**
|
||||
* Geo Shape
|
||||
*/
|
||||
shape: Polygon | ESEnvelope;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user