implement query sorting (#63)

This commit is contained in:
Tom Kralidis
2018-11-17 00:13:05 +00:00
parent c621b21391
commit d2b76936e6
9 changed files with 93 additions and 7 deletions
+32 -1
View File
@@ -351,15 +351,46 @@ class API(object):
if k not in reserved_fieldnames and k in p.fields.keys():
properties.append((k, v))
LOGGER.debug('processing sort parameter')
val = args.get('sortby')
if val is not None:
sortby = []
sorts = val.split(',')
for s in sorts:
if ':' in s:
prop, order = s.split(':')
if order not in ['A', 'D']:
exception = {
'code': 'InvalidParameterValue',
'description': 'sort order should be A or D'
}
LOGGER.error(exception)
return headers_, 400, json.dumps(exception)
sortby.append({'property': prop, 'order': order})
else:
sortby.append({'property': s, 'order': 'A'})
for s in sortby:
if s['property'] not in p.fields.keys():
exception = {
'code': 'InvalidParameterValue',
'description': 'bad sort property'
}
LOGGER.error(exception)
return headers_, 400, json.dumps(exception)
else:
sortby = []
LOGGER.debug('Querying provider')
LOGGER.debug('startindex: {}'.format(startindex))
LOGGER.debug('limit: {}'.format(limit))
LOGGER.debug('resulttype: {}'.format(resulttype))
LOGGER.debug('sortby: {}'.format(sortby))
try:
content = p.query(startindex=int(startindex), limit=int(limit),
resulttype=resulttype, bbox=bbox, time=time,
properties=properties)
properties=properties, sortby=sortby)
except ProviderConnectionError:
exception = {
'code': 'NoApplicableCode',
+2 -1
View File
@@ -109,7 +109,7 @@ class CSVProvider(BaseProvider):
return feature_collection
def query(self, startindex=0, limit=10, resulttype='results',
bbox=[], time=None, properties=[]):
bbox=[], time=None, properties=[], sortby=[]):
"""
CSV query
@@ -119,6 +119,7 @@ class CSVProvider(BaseProvider):
:param bbox: bounding box [minx,miny,maxx,maxy]
:param time: temporal (datestamp or extent)
:param properties: list of tuples (name, value)
:param sortby: list of dicts (property, order)
:returns: dict of GeoJSON FeatureCollection
"""
+27 -1
View File
@@ -98,7 +98,7 @@ class ElasticsearchProvider(BaseProvider):
return fields_
def query(self, startindex=0, limit=10, resulttype='results',
bbox=[], time=None, properties=[]):
bbox=[], time=None, properties=[], sortby=[]):
"""
query Elasticsearch index
@@ -108,6 +108,7 @@ class ElasticsearchProvider(BaseProvider):
:param bbox: bounding box [minx,miny,maxx,maxy]
:param time: temporal (datestamp or extent)
:param properties: list of tuples (name, value)
:param sortby: list of dicts (property, order)
:returns: dict of 0..n GeoJSON features
"""
@@ -181,6 +182,31 @@ class ElasticsearchProvider(BaseProvider):
}
query['query']['bool']['filter'].append(pf)
if sortby:
LOGGER.debug('processing sortby')
query['sort'] = []
for sort in sortby:
LOGGER.debug('processing sort object: {}'.format(sort))
sp = sort['property']
if self.fields[sp]['type'] == 'string':
LOGGER.debug('setting ES .raw on property')
sort_property = 'properties.{}.raw'.format(sp)
else:
sort_property = 'properties.{}'.format(sp)
sort_order = 'asc'
if sort['order'] == 'D':
sort_order = 'desc'
sort_ = {
sort_property: {
'order': sort_order
}
}
query['sort'].append(sort_)
try:
LOGGER.debug('querying Elasticsearch')
if startindex + limit > 10000:
+2 -1
View File
@@ -90,7 +90,7 @@ class GeoJSONProvider(BaseProvider):
return data
def query(self, startindex=0, limit=10, resulttype='results',
bbox=[], time=None, properties=[]):
bbox=[], time=None, properties=[], sortby=[]):
"""
query the provider
@@ -100,6 +100,7 @@ class GeoJSONProvider(BaseProvider):
:param bbox: bounding box [minx,miny,maxx,maxy]
:param time: temporal (datestamp or extent)
:param properties: list of tuples (name, value)
:param sortby: list of dicts (property, order)
:returns: FeatureCollection dict of 0..n GeoJSON features
"""
+2 -1
View File
@@ -185,7 +185,7 @@ class GeoPackageProvider(BaseProvider):
self.cursor.execute("SELECT AutoGPKGStop()")
def query(self, startindex=0, limit=10, resulttype='results',
bbox=[], time=None, properties=[]):
bbox=[], time=None, properties=[], sortby=[]):
"""
Query Geopackage for all the content.
e,g: http://localhost:5000/collections/poi/items?
@@ -197,6 +197,7 @@ class GeoPackageProvider(BaseProvider):
:param bbox: bounding box [minx,miny,maxx,maxy]
:param time: temporal (datestamp or extent)
:param properties: list of tuples (name, value)
:param sortby: list of dicts (property, order)
:returns: GeoJSON FeaturesCollection
"""
+2 -1
View File
@@ -156,7 +156,7 @@ class PostgreSQLProvider(BaseProvider):
LOGGER.debug('Table:{}'.format(self.table))
def query(self, startindex=0, limit=10, resulttype='results',
bbox=[], time=None, properties=[]):
bbox=[], time=None, properties=[], sortby=[]):
"""
Query Postgis for all the content.
e,g: http://localhost:5000/collections/hotosm_bdi_waterways/items?
@@ -168,6 +168,7 @@ class PostgreSQLProvider(BaseProvider):
:param bbox: bounding box [minx,miny,maxx,maxy]
:param time: temporal (datestamp or extent)
:param properties: list of tuples (name, value)
:param sortby: list of dicts (property, order)
:returns: GeoJSON FeaturesCollection
"""
+2 -1
View File
@@ -151,7 +151,7 @@ class SQLiteProvider(BaseProvider):
return cursor
def query(self, startindex=0, limit=10, resulttype='results',
bbox=[], time=None, properties=[]):
bbox=[], time=None, properties=[], sortby=[]):
"""
Query Sqlite for all the content.
e,g: http://localhost:5000/collections/countries/items?
@@ -163,6 +163,7 @@ class SQLiteProvider(BaseProvider):
:param bbox: bounding box [minx,miny,maxx,maxy]
:param time: temporal (datestamp or extent)
:param properties: list of tuples (name, value)
:param sortby: list of dicts (property, order)
:returns: GeoJSON FeaturesCollection
"""
+12
View File
@@ -52,6 +52,18 @@ settings = {
'properties': {
'geometry': {
'type': 'geo_shape'
},
'properties': {
'properties': {
'nameascii': {
'type': 'text',
'fields': {
'raw': {
'type': 'keyword'
}
}
}
}
}
}
}
+12
View File
@@ -63,6 +63,18 @@ def test_query(config):
assert len(results['features']) == 1
assert results['features'][0]['ID'] == 1559804
results = p.query(sortby=[{'property': 'nameascii', 'order': 'A'}])
assert results['features'][0]['properties']['nameascii'] == 'Abidjan'
results = p.query(sortby=[{'property': 'nameascii', 'order': 'D'}])
assert results['features'][0]['properties']['nameascii'] == 'Zagreb'
results = p.query(sortby=[{'property': 'scalerank', 'order': 'A'}])
assert results['features'][0]['properties']['scalerank'] == 0
results = p.query(sortby=[{'property': 'scalerank', 'order': 'D'}])
assert results['features'][0]['properties']['scalerank'] == 8
def test_get(config):
p = ElasticsearchProvider(config)