diff --git a/nomad/app/v1/models/models.py b/nomad/app/v1/models/models.py index c94fab8f96e098eb1bf8968466fc45ec3c251732..a2b9b63ded86708bec05e36e869264eda3933b40 100644 --- a/nomad/app/v1/models/models.py +++ b/nomad/app/v1/models/models.py @@ -912,6 +912,8 @@ class MetadataBasedPagination(Pagination): @validator('order_by') def validate_order_by(cls, order_by): # pylint: disable=no-self-argument # No validation here – validation is done during search + if order_by == 'mainfile_path': + return 'mainfile' return order_by @validator('page_after_value') diff --git a/nomad/app/v1/routers/graph.py b/nomad/app/v1/routers/graph.py index 13a6817fc3df66aeec296bf6a3000afaa5c10c4a..a6aeaea909c3c54fe90822b399ba61405c2041db 100644 --- a/nomad/app/v1/routers/graph.py +++ b/nomad/app/v1/routers/graph.py @@ -38,7 +38,7 @@ def normalise_response(response): if GeneralReader.__CACHE__ in response: del response[GeneralReader.__CACHE__] - return reorder_children(response) + return response def relocate_children(request): @@ -49,18 +49,6 @@ def relocate_children(request): relocate_children(child) -def reorder_children(query): - if not isinstance(query, dict): - return query - # do not touch folders - if 'm_is' in query: - return {k: reorder_children(v) for k, v in query.items()} - return { - k: reorder_children(v) - for k, v in sorted(query.items(), key=lambda item: item[0]) - } - - @router.post( '/raw_query', tags=[default_tag], diff --git a/nomad/app/v1/routers/uploads.py b/nomad/app/v1/routers/uploads.py index 595ef7cfc762bc9ae75c3926ca18090727b54f0b..8daa0d22b70130f2f26c099e293c76087d69c0dd 100644 --- a/nomad/app/v1/routers/uploads.py +++ b/nomad/app/v1/routers/uploads.py @@ -247,6 +247,8 @@ upload_proc_data_pagination_parameters = parameter_dependency_from_model( class EntryProcDataPagination(Pagination): @validator('order_by') def validate_order_by(cls, order_by): # pylint: disable=no-self-argument + if order_by == 'mainfile_path': + return 'mainfile' if order_by is None: return 'mainfile' # Default value assert order_by in ( @@ -254,6 +256,7 @@ class EntryProcDataPagination(Pagination): 'parser_name', 'process_status', 'current_process', + 'entry_create_time', ), 'order_by must be a valid attribute' return order_by diff --git a/nomad/graph/graph_reader.py b/nomad/graph/graph_reader.py index ad5578202d3b0aae5d7510330bcb3577d1dba813..a5174902521e2cc2ddbfbf1df8b7687fcefec602 100644 --- a/nomad/graph/graph_reader.py +++ b/nomad/graph/graph_reader.py @@ -387,7 +387,7 @@ def _populate_result(container_root: dict, path: list, value, *, path_like=False logger.warning(f'Cannot merge {a[i]} and {v}, potential conflicts.') def _merge_dict(a: dict, b: dict): - for k, v in sorted(b.items(), key=lambda item: item[0]): + for k, v in b.items(): if k not in a or a[k] is None: a[k] = v elif isinstance(a[k], set) and isinstance(v, set): @@ -1393,10 +1393,13 @@ class MongoReader(GeneralReader): filtered, child_config, transformer ) if pagination is not None: + pagination_dict = pagination.dict() + if pagination_dict.get('order_by', None) == 'mainfile': + pagination_dict['order_by'] = 'mainfile_path' _populate_result( node.result_root, response_path + ['pagination'], - pagination.dict(), + pagination_dict, ) self._walk( node.replace( @@ -1528,7 +1531,7 @@ class MongoReader(GeneralReader): if wildcard: assert omit_keys is not None - for key in sorted(node.archive.keys()): + for key in node.archive.keys(): new_config: dict = {'property_name': key, 'index': None} if wildcard: if any(k.startswith(key) for k in omit_keys): @@ -2024,7 +2027,11 @@ class FileSystemReader(GeneralReader): path_like=True, ) - for index, file in enumerate(itertools.chain(folders, files)): + whole_list = itertools.chain(folders, files) + if pagination.get('order', 'asc') != 'asc': + whole_list = itertools.chain(reversed(files), reversed(folders)) + + for index, file in enumerate(whole_list): if index >= end: break @@ -2368,7 +2375,7 @@ class ArchiveReader(GeneralReader): _populate_result(node.result_root, node.current_path, result_to_write) return - for key in sorted(node.archive.keys()): + for key in node.archive.keys(): if key == Token.DEF: continue diff --git a/nomad/processing/data.py b/nomad/processing/data.py index 52f1061498e735dd494b12a2dbbe8698315a1e44..e356ce341755d5f664c305e1d80e447af79d7519 100644 --- a/nomad/processing/data.py +++ b/nomad/processing/data.py @@ -946,6 +946,7 @@ class Entry(Proc): ('upload_id', 'nomad_version'), 'process_status', 'last_processing_time', + 'entry_create_time', 'datasets', 'pid', ], diff --git a/tests/graph/test_graph_reader.py b/tests/graph/test_graph_reader.py index e38f66e883fd39dd6805a8ea1efed66d82dc4a5c..7cdd66352e8741ce5f6b1070606ef38f9380e070 100644 --- a/tests/graph/test_graph_reader.py +++ b/tests/graph/test_graph_reader.py @@ -2310,24 +2310,27 @@ def test_general_reader(json_dict, example_data_with_reference, user1): } }, ) - __ge_print( - 'general start from entry WITHOUT retrieval of metadata (just listing)', - { - Token.SEARCH: { - 'm_request': { - 'directive': 'plain', - 'pagination': {'page_size': 2, 'page': 2}, - 'query': {'owner': 'user'}, - }, - } - }, - result={ - Token.SEARCH: { - 'id_03': 'id_03', - 'id_04': 'id_04', - } - }, - ) + # only check if those keys work + # the result order is not checked + for order_by in ['entry_create_time', 'mainfile_path']: + __ge_print( + 'general start from entry WITHOUT retrieval of metadata (just listing)', + { + Token.SEARCH: { + 'm_request': { + 'directive': 'plain', + 'pagination': {'page_size': 2, 'page': 2, 'order_by': order_by}, + 'query': {'owner': 'user'}, + }, + } + }, + result={ + Token.SEARCH: { + 'id_03': 'id_03', + 'id_04': 'id_04', + } + }, + ) __ge_print( 'general start from upload', { @@ -2377,6 +2380,30 @@ def test_general_reader(json_dict, example_data_with_reference, user1): } }, ) + # only check if those keys work + # the result order is not checked + for order_by in ['entry_create_time', 'mainfile_path']: + __ge_print( + 'general start from entry with query and pagination', + { + Token.ENTRIES: { + 'm_request': { + 'directive': 'plain', + 'pagination': {'page_size': 10, 'order_by': order_by}, + }, + } + }, + result={ + 'entries': { + 'id_01': 'id_01', + 'id_02': 'id_02', + 'id_03': 'id_03', + 'id_04': 'id_04', + 'id_05': 'id_05', + 'id_06': 'id_06', + } + }, + ) __ge_print( 'general start from upload with query and pagination', {