diff --git a/salinic/backends/solr/client.py b/salinic/backends/solr/client.py index e8a2bc5..70638c5 100644 --- a/salinic/backends/solr/client.py +++ b/salinic/backends/solr/client.py @@ -19,8 +19,8 @@ class ClientRW(Base): def search(self, sq: SearchQuery, user_id: str | None = None): payload = { 'q': sq.query.original_query, - 'rows': sq.rows, - 'start': sq.start, + 'rows': sq.page_size, + 'start': sq.page_size * (sq.page_number - 1), } if user_id: diff --git a/salinic/backends/solr/index.py b/salinic/backends/solr/index.py index d6bd8ca..3bc7a39 100644 --- a/salinic/backends/solr/index.py +++ b/salinic/backends/solr/index.py @@ -6,7 +6,7 @@ from salinic.field import Field from salinic.query import SearchQuery -from salinic.schema import DocumentPage, Folder +from salinic.schema import DocumentPage, Folder, PaginatedResponse from salinic.utils import first logger = logging.getLogger(__name__) @@ -21,10 +21,14 @@ def search( self, sq: SearchQuery, user_id: str | None = None - ) -> list[DocumentPage | Folder]: + ) -> PaginatedResponse: """Query index""" result = self.client.search(sq, user_id) items = glom(result, 'response.docs') + total_found = glom(result, 'response.numFound') + start = glom(result, 'response.start') + page_number = int(start / sq.page_size) + 1 + num_pages = int(total_found / sq.page_size) + 1 returned_list = [] for item in items: @@ -52,7 +56,12 @@ def search( ) returned_list.append(folder) - return returned_list + return PaginatedResponse( + page_size=sq.page_size, + page_number=page_number, + num_pages=num_pages, + items=returned_list + ) class IndexRW(Base): diff --git a/salinic/query.py b/salinic/query.py index 8e40363..770be9b 100644 --- a/salinic/query.py +++ b/salinic/query.py @@ -169,26 +169,20 @@ def __repr__(self): class SearchQuery: query: Query - rows: int - start: int - group_limit: int - group_offset: int + page_number: int # starts with 1 + page_size: int def __init__( self, entity, q: str, - rows: int = 100, - start: int = 0, - group_limit: int = 100, - group_offset: int = 0 + page_size: int = 50, + page_number: int = 1 ): self.entity = entity self.query = Query(q) - self.rows = rows - self.start = start - self.group_limit = group_limit - self.group_offset = group_offset + self.page_size = page_size + self.page_number = page_number def __str__(self): return f"SearchQuery(query={self.query}, entity={self.entity})" diff --git a/salinic/schema.py b/salinic/schema.py index cf0d6c8..a24aac0 100644 --- a/salinic/schema.py +++ b/salinic/schema.py @@ -105,3 +105,12 @@ class Folder(SearchResultItem): def __hash__(self): return hash(self.model_dump_json()) + + +class PaginatedResponse(BaseModel): + page_size: int + page_number: int + num_pages: int + items: list[Folder | DocumentPage] + + model_config = ConfigDict(from_attributes=True) diff --git a/tests/backends/solr/test_index_search.py b/tests/backends/solr/test_index_search.py index 2981bc1..a0866ed 100644 --- a/tests/backends/solr/test_index_search.py +++ b/tests/backends/solr/test_index_search.py @@ -1,7 +1,7 @@ from typing_extensions import Annotated from salinic import IdField, IndexRO, Search, TextField, create_engine -from salinic.schema import DocumentPage, Folder, Schema +from salinic.schema import DocumentPage, Folder, PaginatedResponse, Schema class Index(Schema): @@ -48,7 +48,7 @@ def test_index_search_result_with_two_folders(requests_mock): 'http://localhost:8983/solr/index/select?q=my+document', json=json_response ) - results = index.search(sq) + results: PaginatedResponse = index.search(sq) expected = { Folder( @@ -63,7 +63,7 @@ def test_index_search_result_with_two_folders(requests_mock): ) } - assert set(results) == expected + assert set(results.items) == expected def test_index_search_result_with_folders_and_documents(requests_mock): @@ -120,7 +120,7 @@ def test_index_search_result_with_folders_and_documents(requests_mock): 'http://localhost:8983/solr/index/select?q=my+document', json=json_response ) - results = index.search(sq) + results: PaginatedResponse = index.search(sq) expected = { Folder( @@ -150,5 +150,5 @@ def test_index_search_result_with_folders_and_documents(requests_mock): tags=[] ) } - assert len(results) == len(expected) - assert set(results) == expected + assert len(results.items) == len(expected) + assert set(results.items) == expected