diff --git a/pygeoapi/api.py b/pygeoapi/api.py index 5009d83..cb801d3 100644 --- a/pygeoapi/api.py +++ b/pygeoapi/api.py @@ -906,27 +906,21 @@ class API: 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, to_json(exception, - self.pretty_print) - 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(): + prop = s + order = '+' + if s[0] in ['+', '-']: + order = s[0] + prop = s[1:] + + if prop not in p.fields.keys(): exception = { 'code': 'InvalidParameterValue', 'description': 'bad sort property' } LOGGER.error(exception) return headers_, 400, to_json(exception, self.pretty_print) + + sortby.append({'property': prop, 'order': order}) else: sortby = [] diff --git a/pygeoapi/openapi.py b/pygeoapi/openapi.py index 232b76b..c8b49b8 100644 --- a/pygeoapi/openapi.py +++ b/pygeoapi/openapi.py @@ -295,17 +295,6 @@ def get_oas_30(cfg): 'default': False } }, - 'sortby': { - 'name': 'sortby', - 'in': 'query', - 'description': 'The optional sortby parameter indicates the sort property and order on which the server shall present results in the response document using the convention `sortby=PROPERTY:X`, where `PROPERTY` is the sort property and `X` is the sort order (`A` is ascending, `D` is descending). Sorting by multiple properties is supported by providing a comma-separated list.', # noqa - 'required': False, - 'schema': { - 'type': 'string', - }, - 'style': 'form', - 'explode': False - }, 'startindex': { 'name': 'startindex', 'in': 'query', @@ -449,7 +438,7 @@ def get_oas_30(cfg): {'$ref': '{}#/components/parameters/limit'.format(OPENAPI_YAML['oapif'])}, # noqa coll_properties, {'$ref': '#/components/parameters/skipGeometry'}, - {'$ref': '#/components/parameters/sortby'}, + {'$ref': '{}/parameters/sortby.yaml'.format(OPENAPI_YAML['oapir'])}, # noqa {'$ref': '#/components/parameters/startindex'}, ], 'responses': { diff --git a/pygeoapi/provider/elasticsearch_.py b/pygeoapi/provider/elasticsearch_.py index 98bf41f..1549f59 100644 --- a/pygeoapi/provider/elasticsearch_.py +++ b/pygeoapi/provider/elasticsearch_.py @@ -227,7 +227,7 @@ class ElasticsearchProvider(BaseProvider): sort_property = self.mask_prop(sp) sort_order = 'asc' - if sort['order'] == 'D': + if sort['order'] == '-': sort_order = 'desc' sort_ = { diff --git a/pygeoapi/provider/mongo.py b/pygeoapi/provider/mongo.py index b851a58..55b042f 100644 --- a/pygeoapi/provider/mongo.py +++ b/pygeoapi/provider/mongo.py @@ -123,7 +123,7 @@ class MongoProvider(BaseProvider): filterobj = {'$and': and_filter} if and_filter else {} sort_list = [("properties." + sort['property'], - ASCENDING if (sort['order'] == 'A') else DESCENDING) + ASCENDING if (sort['order'] == '+') else DESCENDING) for sort in sortby] featurelist, matchcount = self._get_feature_list(filterobj, diff --git a/pygeoapi/provider/tinydb_.py b/pygeoapi/provider/tinydb_.py index 689f0e2..e6f06cf 100644 --- a/pygeoapi/provider/tinydb_.py +++ b/pygeoapi/provider/tinydb_.py @@ -191,7 +191,7 @@ class TinyDBCatalogueProvider(BaseProvider): if sortby: LOGGER.debug('Sorting results') - if sortby[0]['order'] == 'D': + if sortby[0]['order'] == '-': sort_reverse = True else: sort_reverse = False diff --git a/tests/pygeoapi-test-openapi.yml b/tests/pygeoapi-test-openapi.yml index 6b8332a..e29e79e 100644 --- a/tests/pygeoapi-test-openapi.yml +++ b/tests/pygeoapi-test-openapi.yml @@ -45,17 +45,16 @@ components: type: string style: form sortby: - description: The optional sortby parameter indicates the sort property and order - on which the server shall present results in the response document using the - convention `sortby=PROPERTY:X`, where `PROPERTY` is the sort property and - `X` is the sort order (`A` is ascending, `D` is descending). Sorting by multiple - properties is supported by providing a comma-separated list. - explode: false - in: query name: sortby + in: query required: false schema: - type: string + type: array + minItems: 1 + items: + type: string + pattern: "[+|-][A-Za-z_][A-Za-z_0-9]*" + explode: false style: form startindex: description: The optional startindex parameter indicates the index within the diff --git a/tests/test_api.py b/tests/test_api.py index 902959d..5d42b22 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -439,18 +439,18 @@ def test_get_collection_items(config, api_): assert code == 400 rsp_headers, code, response = api_.get_collection_items( - req_headers, { - 'sortby': 'stn_id:FOO', - 'stn_id': '35', - 'value': '89.9' - }, 'obs') - - assert code == 400 + req_headers, {'sortby': 'stn_id'}, 'obs') + features = json.loads(response) + assert code == 200 rsp_headers, code, response = api_.get_collection_items( - req_headers, {'sortby': 'stn_id:A'}, 'obs') + req_headers, {'sortby': '+stn_id'}, 'obs') + features = json.loads(response) + assert code == 200 + + rsp_headers, code, response = api_.get_collection_items( + req_headers, {'sortby': '-stn_id'}, 'obs') features = json.loads(response) - # FIXME? this test errors out currently assert code == 200 rsp_headers, code, response = api_.get_collection_items( diff --git a/tests/test_elasticsearch__provider.py b/tests/test_elasticsearch__provider.py index 057fb7a..5f2b4b4 100644 --- a/tests/test_elasticsearch__provider.py +++ b/tests/test_elasticsearch__provider.py @@ -72,21 +72,21 @@ def test_query(config): assert len(results['features']) == 1 assert results['features'][0]['id'] == 3168070 - results = p.query(sortby=[{'property': 'nameascii', 'order': 'A'}]) + results = p.query(sortby=[{'property': 'nameascii', 'order': '+'}]) assert results['features'][0]['properties']['nameascii'] == 'Abidjan' - results = p.query(sortby=[{'property': 'nameascii', 'order': 'D'}]) + results = p.query(sortby=[{'property': 'nameascii', 'order': '-'}]) assert results['features'][0]['properties']['nameascii'] == 'Zagreb' - results = p.query(sortby=[{'property': 'scalerank', 'order': 'A'}]) + results = p.query(sortby=[{'property': 'scalerank', 'order': '+'}]) assert results['features'][0]['properties']['scalerank'] == 0 - results = p.query(sortby=[{'property': 'scalerank', 'order': 'D'}]) + results = p.query(sortby=[{'property': 'scalerank', 'order': '-'}]) assert results['features'][0]['properties']['scalerank'] == 8 assert len(results['features'][0]['properties']) == 37 - results = p.query(sortby=[{'property': 'nameascii', 'order': 'D'}], + results = p.query(sortby=[{'property': 'nameascii', 'order': '-'}], limit=10001) assert results['features'][0]['properties']['nameascii'] == 'Zagreb' assert len(results['features']) == 242 diff --git a/tests/test_mongo_provider.py b/tests/test_mongo_provider.py index 7c63c86..dfdff10 100644 --- a/tests/test_mongo_provider.py +++ b/tests/test_mongo_provider.py @@ -82,16 +82,16 @@ def test_query(config): assert len(results['features']) == 1 assert results['features'][0]['properties']['nameascii'] == 'Vaduz' - results = p.query(sortby=[{'property': 'nameascii', 'order': 'A'}]) + results = p.query(sortby=[{'property': 'nameascii', 'order': '+'}]) assert results['features'][0]['properties']['nameascii'] == 'Abidjan' - results = p.query(sortby=[{'property': 'nameascii', 'order': 'D'}]) + results = p.query(sortby=[{'property': 'nameascii', 'order': '-'}]) assert results['features'][0]['properties']['nameascii'] == 'Zagreb' - results = p.query(sortby=[{'property': 'scalerank', 'order': 'A'}]) + results = p.query(sortby=[{'property': 'scalerank', 'order': '+'}]) assert results['features'][0]['properties']['scalerank'] == 0 - results = p.query(sortby=[{'property': 'scalerank', 'order': 'D'}]) + results = p.query(sortby=[{'property': 'scalerank', 'order': '-'}]) assert results['features'][0]['properties']['scalerank'] == 8 assert len(results['features'][0]['properties']) == 37 diff --git a/tests/test_tinydb_catalogue_provider.py b/tests/test_tinydb_catalogue_provider.py index c1c5992..d76c511 100644 --- a/tests/test_tinydb_catalogue_provider.py +++ b/tests/test_tinydb_catalogue_provider.py @@ -107,10 +107,10 @@ def test_query(config): assert len(results['features']) == 2 assert results['features'][0]['id'] == 'd3028ad0-b0d0-47ff-bcc3-d383881e17cd' # noqa - results = p.query(sortby=[{'property': 'title', 'order': 'A'}]) + results = p.query(sortby=[{'property': 'title', 'order': '+'}]) assert results['features'][0]['id'] == '1687cac6-ee13-4866-ab8a-114c2ede7b13' # noqa - results = p.query(sortby=[{'property': 'title', 'order': 'D'}]) + results = p.query(sortby=[{'property': 'title', 'order': '-'}]) assert results['features'][0]['id'] == '8a09413a-0a01-4aab-8925-720d987deb20' # noqa