Source code for api.users.filters
from elasticsearch_dsl import Q
from rest_framework.filters import BaseFilterBackend
from rest_framework.settings import api_settings
from apps.users.documents import UserDocument
[docs]
class UserElasticsearchFilter(BaseFilterBackend):
"""
Filter for performing user search using Elasticsearch.
Executes search on username, first_name, and last_name with different weights.
"""
[docs]
def construct_query(self, search_param):
"""
Constructs a combined Elasticsearch query from various parts.
:param search_param: The search parameter entered by the user.
:return: A combined Elasticsearch query.
"""
# Queries for each parameter
username_query = Q("match", username={"query": search_param, "fuzziness": "AUTO", "boost": 4})
first_name_query = Q("match", first_name={"query": search_param, "fuzziness": "AUTO", "boost": 3})
last_name_query = Q("match", last_name={"query": search_param, "fuzziness": "AUTO", "boost": 2})
# Combine the queries
combined_query = Q(
"bool",
should=[
username_query,
first_name_query,
last_name_query,
],
)
return combined_query
[docs]
def filter_queryset(self, request, queryset, view):
"""
Filters a QuerySet based on the search parameters in the request.
:param request: HTTP request object.
:param queryset: Initial QuerySet.
:param view: The view that calls this method.
:return: Updated QuerySet.
"""
search_param = request.query_params.get("search")
offset = int(request.query_params.get("offset", 0))
limit = int(request.query_params.get("limit", api_settings.PAGE_SIZE))
if search_param:
combined_query = self.construct_query(search_param)
search = UserDocument.search().query(combined_query)
total_results = search.count()
if offset >= total_results:
return queryset.none()
end = offset + limit
search = search[offset:end]
queryset = search.to_queryset()
queryset.search_count = total_results
return queryset