diff --git a/prez/config.py b/prez/config.py index a3f507b4..a14390ba 100755 --- a/prez/config.py +++ b/prez/config.py @@ -40,6 +40,7 @@ class Settings(BaseSettings): system_uri: Optional[str] = f"{protocol}://{host}:{port}" order_lists_by_label: bool = True listing_count_limit: int = 100 + search_count_limit: int = 10 label_predicates: Optional[List[URIRef]] = [ SKOS.prefLabel, DCTERMS.title, diff --git a/prez/dependencies.py b/prez/dependencies.py index 679309ee..7581b39a 100755 --- a/prez/dependencies.py +++ b/prez/dependencies.py @@ -171,8 +171,8 @@ async def generate_search_query(request: Request): escaped_term = escape_for_lucene_and_sparql(term) predicates = request.query_params.getlist("predicates") page = request.query_params.get("page", 1) - per_page = request.query_params.get("per_page", 10) - limit = int(per_page) + per_page = request.query_params.get("per_page") + limit = int(per_page) if per_page else settings.search_count_limit offset = limit * (int(page) - 1) return SearchQueryRegex( diff --git a/prez/services/listings.py b/prez/services/listings.py index 5598b7c2..d14fb954 100755 --- a/prez/services/listings.py +++ b/prez/services/listings.py @@ -7,6 +7,7 @@ from sparql_grammar_pydantic import IRI, Var, TriplesSameSubject from prez.cache import endpoints_graph_cache +from prez.config import settings from prez.reference_data.prez_ns import PREZ, ALTREXT, ONT from prez.renderers.renderer import return_from_graph from prez.services.link_generation import add_prez_links @@ -98,7 +99,11 @@ async def listing_function( # count search results - hard to do in SPARQL as the SELECT part of the query is NOT aggregated if search_query: count = len(list(item_graph.subjects(RDF.type, PREZ.SearchResult))) - item_graph.add((PREZ.SearchResult, PREZ["count"], Literal(count))) + if count == search_query.limit: + count_literal = f">{count-1}" + else: + count_literal = f"{count}" + item_graph.add((PREZ.SearchResult, PREZ["count"], Literal(count_literal))) return await return_from_graph( item_graph, pmts.selected["mediatype"], diff --git a/prez/services/query_generation/search.py b/prez/services/query_generation/search.py index fab138ae..b4bbb20a 100755 --- a/prez/services/query_generation/search.py +++ b/prez/services/query_generation/search.py @@ -46,25 +46,25 @@ class SearchQueryRegex(ConstructQuery): - limit: int = 10 # specify here to make available as attribute - offset: int = 0 # specify here to make available as attribute - def __init__( self, term: str, + limit: int, + offset: int, predicates: Optional[List[str]] = None, - limit: int = 10, - offset: int = 0, ): + + limit += 1 # increase the limit by one so we know if there are further pages of results. + + if not predicates: + predicates = settings.default_search_predicates + sr_uri: Var = Var(value="focus_node") pred: Var = Var(value="pred") match: Var = Var(value="match") weight: Var = Var(value="weight") hashid: Var = Var(value="hashID") - if not predicates: - predicates = settings.default_search_predicates - ct_map = { IRI(value=PREZ.searchResultWeight): weight, IRI(value=PREZ.searchResultPredicate): pred, @@ -376,3 +376,11 @@ def order_by(self): @property def order_by_direction(self): return "DESC" + + @property + def limit(self): + return self.where_clause.group_graph_pattern.content.solution_modifier.limit_offset.limit_clause.limit + + @property + def offset(self): + return self.where_clause.group_graph_pattern.content.solution_modifier.limit_offset.offset_clause.offset diff --git a/tests/test_query_construction.py b/tests/test_query_construction.py index afbd57da..c1693175 100755 --- a/tests/test_query_construction.py +++ b/tests/test_query_construction.py @@ -102,7 +102,7 @@ def test_basic_listing(): def test_search_query_regex(): - sq = SearchQueryRegex(term="test", predicates=[RDFS.label]) + sq = SearchQueryRegex(term="test", predicates=[RDFS.label], limit=10, offset=0) test = PrezQueryConstructor( profile_triples=[ TriplesSameSubjectPath.from_spo(