From b838e57f55385f60c2f2288f03935e5621b5602c Mon Sep 17 00:00:00 2001 From: david Date: Thu, 15 Aug 2024 10:52:41 +1000 Subject: [PATCH] fix: search counts behave the same as other counts; returns a string with the number of results or if at the limit=n+1 then ">n" as a string --- prez/config.py | 1 + prez/dependencies.py | 4 ++-- prez/services/listings.py | 7 ++++++- prez/services/query_generation/search.py | 24 ++++++++++++++++-------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/prez/config.py b/prez/config.py index b1df20ac..eadccdf9 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 = 1000 + 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..8e8ea6a9 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 == settings.search_count_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..4fa3ad94 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, predicates: Optional[List[str]] = None, - limit: int = 10, - offset: int = 0, + limit: int = None, + offset: int = None, ): + + 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