(backend) handle sub-document filter and remove pagination

I am adding the path params to the search endpoint.
It represents the path to the parent.
This allows searching in subdocs.
I am also removing the pagination from the idnexer.
We also want to remove db access. All necessary
information
are indexed in FInd.
This leads to removing the pagination handled by the queryset.
This commit is contained in:
charles
2026-03-17 16:51:17 +01:00
parent e67ae1565d
commit 9aa685fc96
3 changed files with 32 additions and 42 deletions
+1 -4
View File
@@ -1005,7 +1005,4 @@ class SearchDocumentSerializer(serializers.Serializer):
"""Serializer for fulltext search requests through Find application"""
q = serializers.CharField(required=True, allow_blank=False, trim_whitespace=True)
page_size = serializers.IntegerField(
required=False, min_value=1, max_value=50, default=20
)
page = serializers.IntegerField(required=False, min_value=1, default=1)
path = serializers.CharField(required=False, allow_blank=False)
+23 -33
View File
@@ -1402,7 +1402,7 @@ class DocumentViewSet(
Returns a queryset filtered by the content of the document title
"""
# As the 'list' view we get a prefiltered queryset (deleted docs are excluded)
queryset = self.get_queryset()
queryset = models.Document.objects.all()
filterset = DocumentFilter({"title": text}, queryset=queryset)
if not filterset.is_valid():
@@ -1417,58 +1417,48 @@ class DocumentViewSet(
},
)
def _search_fulltext(self, indexer, request, params):
@staticmethod
def _search_with_indexer(indexer, request, params):
"""
Returns a queryset from the results the fulltext search of Find
Returns a list of documents matching the query (q) according to the configured indexer.
"""
access_token = request.session.get("oidc_access_token")
user = request.user
text = params.validated_data["q"]
queryset = models.Document.objects.all()
# Retrieve the documents ids from Find.
results = indexer.search(
text=text,
token=access_token,
visited=get_visited_document_ids_of(queryset, user),
q=params.validated_data["q"],
token=request.session.get("oidc_access_token"),
path=(
params.validated_data["path"]
if "path" in params.validated_data
else None
),
visited=get_visited_document_ids_of(queryset, request.user),
)
docs_by_uuid = {str(d.pk): d for d in queryset.filter(pk__in=results)}
ordered_docs = [docs_by_uuid[id] for id in results]
page = self.paginate_queryset(ordered_docs)
serializer = self.get_serializer(
page if page else ordered_docs,
many=True,
context={
"request": request,
},
return drf_response.Response(
{
"count": len(results),
"next": None,
"previous": None,
"results": results,
}
)
return self.get_paginated_response(serializer.data)
@drf.decorators.action(detail=False, methods=["get"], url_path="search")
@method_decorator(refresh_oidc_access_token)
def search(self, request, *args, **kwargs):
"""
Returns a DRF response containing the filtered, annotated and ordered document list.
Returns an ordered list of documents best matching the search query parameter 'q'.
Applies filtering based on request parameter 'q' from `SearchDocumentSerializer`.
Depending of the configuration it can be:
- A fulltext search through the opensearch indexation app "find" if the backend is
enabled (see SEARCH_INDEXER_CLASS)
- A filtering by the model field 'title'.
The ordering is always by the most recent first.
It depends on a search configurable Search Indexer. If no Search Indexer is configured or if it
is not reachable, the function falls back to a basic title search.
"""
params = serializers.SearchDocumentSerializer(data=request.query_params)
params.is_valid(raise_exception=True)
indexer = get_document_indexer()
if indexer:
return self._search_fulltext(indexer, request, params=params)
return self._search_with_indexer(indexer, request, params=params)
# The indexer is not configured, we fallback on a simple icontains filter by the
# model field 'title'.
+8 -5
View File
@@ -185,7 +185,7 @@ class BaseDocumentIndexer(ABC):
"""
# pylint: disable-next=too-many-arguments,too-many-positional-arguments
def search(self, text, token, visited=(), nb_results=None):
def search(self, q, token, visited=(), nb_results=None, path=None):
"""
Search for documents in Find app.
Ensure the same default ordering as "Docs" list : -updated_at
@@ -193,7 +193,7 @@ class BaseDocumentIndexer(ABC):
Returns ids of the documents
Args:
text (str): Text search content.
q (str): Text search content.
token (str): OIDC Authentication token.
visited (list, optional):
List of ids of active public documents with LinkTrace
@@ -201,21 +201,24 @@ class BaseDocumentIndexer(ABC):
nb_results (int, optional):
The number of results to return.
Defaults to 50 if not specified.
path (str, optional):
The path to filter documents.
"""
nb_results = nb_results or self.search_limit
response = self.search_query(
results = self.search_query(
data={
"q": text,
"q": q,
"visited": visited,
"services": ["docs"],
"nb_results": nb_results,
"order_by": "updated_at",
"order_direction": "desc",
"path": path,
},
token=token,
)
return [d["_id"] for d in response]
return results
@abstractmethod
def search_query(self, data, token) -> dict: