Multi Index search in django-elasticsearch-dsl, django-elasticsearch-dsl-drf

Hi All,

i’m developing a global search API in django using django-elasticsearch-dsl , django-elasticsearch-dsl-drf. i’ve referred this sample document to develop API. Django REST Framework and Elasticsearch | TestDriven.io

The goal is to search in all index and get the response from elastic search.

In elastic search we have multi index query
GET /user,categories/_search { “query”: { “match”: { “user.id”: “kim” } } }

or

GET /*/_search { “query”: { “match”: { “user.id”: “kim” } } }

the django-elastic-search-dsl as well as django-elastic-search-dsl-drf are using Document.Search().query(q)

.eg:
search = ArticleDocument.Search().query(q)
res = search.execute()

How can i search in all documents Articledocument, CategoryDocument, UserDocument whenever user types something in the search box.

The below view is 3 different where as i want to query in all index and return the result response.
I know there is a separate way like create a elastic search instance and then use Search(index=*) but this is using elasticsearch-dsl. I would like to use django-elasticsearch-dsl, django-elasticsearch-dsl-drf.

Please help me out.


# search/views.py

import abc

from django.http import HttpResponse
from elasticsearch_dsl import Q
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.views import APIView

from blog.documents import ArticleDocument, UserDocument, CategoryDocument
from blog.serializers import ArticleSerializer, UserSerializer, CategorySerializer


class PaginatedElasticSearchAPIView(APIView, LimitOffsetPagination):
    serializer_class = None
    document_class = None

    @abc.abstractmethod
    def generate_q_expression(self, query):
        """This method should be overridden
        and return a Q() expression."""

    def get(self, request, query):
        try:
            q = self.generate_q_expression(query)
            search = self.document_class.search().query(q)
            response = search.execute()

            print(f'Found {response.hits.total.value} hit(s) for query: "{query}"')

            results = self.paginate_queryset(response, request, view=self)
            serializer = self.serializer_class(results, many=True)
            return self.get_paginated_response(serializer.data)
        except Exception as e:
            return HttpResponse(e, status=500)


# views


class SearchUsers(PaginatedElasticSearchAPIView):
    serializer_class = UserSerializer
    document_class = UserDocument

    def generate_q_expression(self, query):
        return Q('bool',
                 should=[
                     Q('match', username=query),
                     Q('match', first_name=query),
                     Q('match', last_name=query),
                 ], minimum_should_match=1)


class SearchCategories(PaginatedElasticSearchAPIView):
    serializer_class = CategorySerializer
    document_class = CategoryDocument

    def generate_q_expression(self, query):
        return Q(
                'multi_match', query=query,
                fields=[
                    'name',
                    'description',
                ], fuzziness='auto')


class SearchArticles(PaginatedElasticSearchAPIView):
    serializer_class = ArticleSerializer
    document_class = ArticleDocument

    def generate_q_expression(self, query):
        return Q(
                'multi_match', query=query,
                fields=[
                    'title',
                    'author',
                    'type',
                    'content'
                ], fuzziness='auto')