diff --git a/invenio_records_rest/config.py b/invenio_records_rest/config.py index fcb61d4..35a64f6 100644 --- a/invenio_records_rest/config.py +++ b/invenio_records_rest/config.py @@ -29,6 +29,7 @@ def _(x): search_class=RecordsSearch, indexer_class=RecordIndexer, search_index=None, + search_query_parser=None, record_serializers={ "application/json": ( "invenio_records_rest.serializers" ":json_v1_response" @@ -80,6 +81,12 @@ def deleted_pid_error_handler(error): 'message': error.description, 'removal_reason': record.get('removal_reason')}), 410) + def query_parser_with_and(qstr=None): + if qstr: + return dsl.Q("query_string", query=qstr, default_operator="AND") + return dsl.Q() + + RECORDS_REST_ENDPOINTS = { 'endpoint-prefix': { 'create_permission_factory_imp': permission_check_factory(), @@ -110,6 +117,7 @@ def deleted_pid_error_handler(error): 'search_class': 'mypackage.utils:mysearchclass', 'search_factory_imp': search_factory(), 'search_index': 'search-index-name', + 'search_query_parser': query_parser_with_and, 'search_serializers': { 'application/json': 'mypackage.utils:my_json_search_serializer' }, @@ -193,6 +201,10 @@ def deleted_pid_error_handler(error): :param search_index: Name of the search index used when searching records. +:param search_query_parser: Name of the function that will be used to parse the + query. The default parser does an 'OR' of all the terms that have been + specified. This could be used to do, as an example, and 'AND' of the terms. + :param search_serializers: It contains the list of records serializers for all supported format. This configuration differ from the previous because in this case it handle a list of records resulted by a search query instead of diff --git a/invenio_records_rest/views.py b/invenio_records_rest/views.py index d422309..9735788 100644 --- a/invenio_records_rest/views.py +++ b/invenio_records_rest/views.py @@ -202,6 +202,7 @@ def create_url_rules( links_factory_imp=None, suggesters=None, default_endpoint_prefix=None, + search_query_parser=None, ): """Create Werkzeug URL rules. @@ -254,6 +255,7 @@ def create_url_rules( :param search_factory_imp: Factory to parse queries. :param links_factory_imp: Factory for record links generation. :param suggesters: Suggester fields configuration. + :param search_query_parser: Function that implements the query parser :returns: a list of dictionaries with can each be passed as keywords arguments to ``Blueprint.add_url_rule``. @@ -325,6 +327,7 @@ def links_factory(pid, record=None, **kwargs): ), item_links_factory=links_factory, record_class=record_class, + search_query_parser=search_query_parser, ) item_view = RecordResource.as_view( RecordResource.view_name.format(endpoint), @@ -591,6 +594,7 @@ def __init__( item_links_factory=None, record_class=None, indexer_class=None, + search_query_parser=None, **kwargs ): """Constructor.""" @@ -623,6 +627,7 @@ def __init__( self.loaders = record_loaders or current_records_rest.loaders self.record_class = record_class or Record self.indexer_class = indexer_class + self.search_query_parser = search_query_parser @need_record_permission("list_permission_factory") @use_paginate_args( @@ -647,7 +652,7 @@ def get(self, pagination=None, **kwargs): search = search[pagination["from_idx"] : pagination["to_idx"]] search = search.extra(track_total_hits=True) - search, qs_kwargs = self.search_factory(search) + search, qs_kwargs = self.search_factory(search, self.search_query_parser) urlkwargs.update(qs_kwargs) # Execute search