django-elasticsearch-dsl-drf

Integrate Elasticsearch DSL with Django REST framework in the shortest way possible, with least efforts possible.

Package provides views, serializers, filter backends, pagination and other handy add-ons.

You are expected to use django-elasticsearch-dsl for defining your Elasticsearch documents.

PyPI Version Build Status GPL-2.0-only OR LGPL-2.1-or-later https://codecov.io/gh/barseghyanartur/django-elasticsearch-dsl-drf/branch/master/graph/badge.svg

Documentation

Documentation is available on Read the Docs.

Make sure to read FAQ.

Prerequisites

  • Django 1.11, 2.0, 2.1 and 2.2.
  • Python 2.7, 3.5, 3.6, 3.7.
  • Elasticsearch 6.x, 7.x. For older versions use django-elasticsearch-dsl-drf version 0.18.

Main features and highlights

Do you need a similar tool for GraphQL? Check graphene-elastic.

Demo

A frontend demo (React based) is available. See the dedicated docs for more information.

To bootstrap evaluation, clone the repository locally and run docker-compose.

docker-compose up

It will set up:

Installation

  1. Install latest stable version from PyPI:

    pip install django-elasticsearch-dsl-drf
    

    or latest stable version from GitHub:

    pip install https://github.com/barseghyanartur/django-elasticsearch-dsl-drf/archive/stable.tar.gz
    

    or latest stable version from BitBucket:

    pip install https://bitbucket.org/barseghyanartur/django-elasticsearch-dsl-drf/get/stable.tar.gz
    
  2. Add rest_framework, django_elasticsearch_dsl and django_elasticsearch_dsl_drf to INSTALLED_APPS:

    INSTALLED_APPS = (
        # ...
        # REST framework
        'rest_framework',
    
        # Django Elasticsearch integration
        'django_elasticsearch_dsl',
    
        # Django REST framework Elasticsearch integration (this package)
        'django_elasticsearch_dsl_drf',
        # ...
    )
    

Quick start

Perhaps the easiest way to get acquainted with django-elasticsearch-dsl-drf is to read the quick start tutorial.

See it as a guide of diving into integration of Elasticsearch with Django with very low knowledge entry level.

Testing

Project is covered with tests.

To test with all supported Python/Django versions type:

tox

To test against specific environment, type:

tox -e py37-django21

To test just your working environment type:

./runtests.py

To run a single test in your working environment type:

./runtests.py src/django_elasticsearch_dsl_drf/tests/test_filtering.py

Or:

./manage.py test django_elasticsearch_dsl_drf.tests.test_ordering

To run a single test class in a given test module in your working environment type:

./runtests.py src/django_elasticsearch_dsl_drf/tests/test_suggesters.py::TestSuggesters

It’s assumed that you have all the requirements installed. If not, first install the test requirements:

pip install -r examples/requirements/test.txt

Writing documentation

Keep the following hierarchy.

=====
title
=====

header
======

sub-header
----------

sub-sub-header
~~~~~~~~~~~~~~

sub-sub-sub-header
^^^^^^^^^^^^^^^^^^

sub-sub-sub-sub-header
++++++++++++++++++++++

sub-sub-sub-sub-sub-header
**************************

License

GPL-2.0-only OR LGPL-2.1-or-later

Support

For any issues contact me at the e-mail given in the Author section.

Project documentation

Contents:

Dependencies

elasticsearch and elasticsearch-dsl

Depending on your Elasticsearch version (either 2.x, 5.x, 6.x or 7.x) you should use 2.x, 5.x, 6.x or 7.x versions of the elasticsearch and elasticsearch-dsl packages accordingly.

Current compatibility matrix is:

This package Elasticsearch
0.20 6.x, 7.x
0.19 6.x
0.18 2.x, 5.x, 6.x

django-elasticsearch-dsl

You are advised to use the latest version of django-elasticsearch-dsl.

The following versions have been tested and work well together:

elasticsearch elasticsearch-dsl django-elasticsearch-dsl
2.4.1 2.2.0 0.5.1
5.4.0 5.3.0 0.5.1
5.4.0 | 5.3.0 | 0.5.1 |

As of django-elasticsearch-dsl-drf 0.19, support for Elasticsearch versions prior 6.x has been dropped.

Django/ Django REST Framework

Initial version of this package was written for djangorestframework 3.6.2.

Starting from django-elasticsearch-dsl-drf version 0.18, support for Django versions prior 1.11 and Django REST Framework versions prior 3.9 has been dropped.

Current compatibility matrix is:

Django Django REST Framework
1.11 3.9.3
2.0 3.9.3
2.1 3.9.3
2.2 3.9.3

The version 0.17.7 has been tested with the following versions of Django and Django REST Framework:

Django Django REST Framework
1.8 3.6.2
1.9 3.6.2
1.10 3.6.2
1.11 3.7.7
2.0 3.7.7
2.1 3.8.2
2.2 3.9.2

Installing Elasticsearch

For development and testing purposes, it’s often handy to be able to quickly switch between different Elasticsearch versions. Since this packages supports 2.x, 5.x and 6.x branches, you could make use of the following boxes/containers for development and testing.

Note

As of django-elasticsearch-dsl-drf 0.19, support for Elasticsearch versions prior 6.x has been dropped.

For all containers/boxes mentioned below, no authentication is required (for Elasticsearch).

Docker

2.x
docker pull elasticsearch:2.4.6
docker run -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" elasticsearch:2.4.6
5.x
docker pull docker.elastic.co/elasticsearch/elasticsearch:5.5.3
docker run -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" docker.elastic.co/elasticsearch/elasticsearch:5.5.3
6.x

6.3.2

docker pull docker.elastic.co/elasticsearch/elasticsearch:6.3.2
docker run -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" docker.elastic.co/elasticsearch/elasticsearch:6.3.2

6.4.0

docker pull docker.elastic.co/elasticsearch/elasticsearch:6.4.0
docker run -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" docker.elastic.co/elasticsearch/elasticsearch:6.4.0
7.x

7.3.0

docker pull docker.elastic.co/elasticsearch/elasticsearch:7.3.0
docker run -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" docker.elastic.co/elasticsearch/elasticsearch:7.3.0

Vagrant

2.x
./scripts/vagrant_start.sh

Quick start

The best way to get acquainted with django-elasticsearch-dsl-drf.

See it as a guide of diving into integration of Elasticsearch with Django with very low knowledge entry level.

Contents:

Installation

  1. Install latest stable version from PyPI:

    pip install django-elasticsearch-dsl-drf
    
  2. Add rest_framework, django_elasticsearch_dsl and django_elasticsearch_dsl_drf to INSTALLED_APPS:

    INSTALLED_APPS = (
        # ...
        # REST framework
        'rest_framework',
    
        # Django Elasticsearch integration
        'django_elasticsearch_dsl',
    
        # Django REST framework Elasticsearch integration (this package)
        'django_elasticsearch_dsl_drf',
        # ...
    )
    
  3. Basic Django REST framework and django-elasticsearch-dsl configuration:

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',
            'rest_framework.authentication.SessionAuthentication',
        ),
        'DEFAULT_PAGINATION_CLASS':
            'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 100,
        'ORDERING_PARAM': 'ordering',
    }
    
    # Elasticsearch configuration
    ELASTICSEARCH_DSL = {
        'default': {
            'hosts': 'localhost:9200'
        },
    }
    

Example app

To get started, let’s imagine we have a simple book register with a couple of models.

  • Publisher model: The book publisher model. Each book might have only one publisher (ForeignKey relation).
  • Author model: The book author model. Each book might have unlimited number of authors (ManyToMany relation).
  • Tag model: The tag model. Each book might have unlimited number of tags (ManyToMany relation).
  • Book model: The book model.

To keep things separate, our Django models will reside in the books app. Elasticsearch documents and Django REST framework views will be defined in a search_indexes app. Both of the apps should be added to the INSTALLED_APPS.

INSTALLED_APPS = (
    # ...
    'books',  # Books application
    'search_indexes',  # Elasticsearch integration with the Django
                       # REST framework
    # ...
)
Sample models

Content of the books/models.py file. Additionally, see the code comments.

Required imports

Imports required for model definition.

books/models/book.py

import json

from django.conf import settings
from django.db import models
from django.utils.translation import ugettext, ugettext_lazy as _

from six import python_2_unicode_compatible
Book statuses

books/models/book.py

# States indicate the publishing status of the book. Publishing might
# be in-progress, not yet published, published, rejected, etc.
BOOK_PUBLISHING_STATUS_PUBLISHED = 'published'
BOOK_PUBLISHING_STATUS_NOT_PUBLISHED = 'not_published'
BOOK_PUBLISHING_STATUS_IN_PROGRESS = 'in_progress'
BOOK_PUBLISHING_STATUS_CANCELLED = 'cancelled'
BOOK_PUBLISHING_STATUS_REJECTED = 'rejected'
BOOK_PUBLISHING_STATUS_CHOICES = (
    (BOOK_PUBLISHING_STATUS_PUBLISHED, "Published"),
    (BOOK_PUBLISHING_STATUS_NOT_PUBLISHED, "Not published"),
    (BOOK_PUBLISHING_STATUS_IN_PROGRESS, "In progress"),
    (BOOK_PUBLISHING_STATUS_CANCELLED, "Cancelled"),
    (BOOK_PUBLISHING_STATUS_REJECTED, "Rejected"),
)
BOOK_PUBLISHING_STATUS_DEFAULT = BOOK_PUBLISHING_STATUS_PUBLISHED
Publisher model

books/models/book.py

@python_2_unicode_compatible
class Publisher(models.Model):
    """Publisher."""

    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()
    latitude = models.DecimalField(null=True,
                               blank=True,
                               decimal_places=15,
                               max_digits=19,
                               default=0)
    longitude = models.DecimalField(null=True,
                                    blank=True,
                                    decimal_places=15,
                                    max_digits=19,
                                    default=0)

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name

    @property
    def location_field_indexing(self):
        """Location for indexing.

        Used in Elasticsearch indexing/tests of `geo_distance` native filter.
        """
        return {
            'lat': self.latitude,
            'lon': self.longitude,
        }
Author model

books/models/author.py

@python_2_unicode_compatible
class Author(models.Model):
    """Author."""

    salutation = models.CharField(max_length=10)
    name = models.CharField(max_length=200)
    email = models.EmailField()
    headshot = models.ImageField(upload_to='authors', null=True, blank=True)

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name
Tag model

books/models/tag.py

class Tag(models.Model):
    """Simple tag model."""

    title = models.CharField(max_length=255, unique=True)

    class Meta(object):
        """Meta options."""

        verbose_name = _("Tag")
        verbose_name_plural = _("Tags")

    def __str__(self):
        return self.title
Book model

books/models/book.py

@python_2_unicode_compatible
class Book(models.Model):
    """Book."""

    title = models.CharField(max_length=100)
    description = models.TextField(null=True, blank=True)
    summary = models.TextField(null=True, blank=True)
    authors = models.ManyToManyField('books.Author', related_name='books')
    publisher = models.ForeignKey(Publisher, related_name='books')
    publication_date = models.DateField()
    state = models.CharField(max_length=100,
                             choices=BOOK_PUBLISHING_STATUS_CHOICES,
                             default=BOOK_PUBLISHING_STATUS_DEFAULT)
    isbn = models.CharField(max_length=100, unique=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    pages = models.PositiveIntegerField(default=200)
    stock_count = models.PositiveIntegerField(default=30)
    tags = models.ManyToManyField('books.Tag',
                                  related_name='books',
                                  blank=True)

    class Meta(object):
        """Meta options."""

        ordering = ["isbn"]

    def __str__(self):
        return self.title

    # The only publisher information we're going to need in our document
    # is the publisher name. Since publisher isn't a required field,
    # we define a properly on a model level to avoid indexing errors on
    # non-existing relation.
    @property
    def publisher_indexing(self):
        """Publisher for indexing.

        Used in Elasticsearch indexing.
        """
        if self.publisher is not None:
            return self.publisher.name

    # As of tags, again, we only need a flat list of tag names, on which
    # we can filter. Therefore, we define a properly on a model level,
    # which will return a JSON dumped list of tags relevant to the
    # current book model object.
    @property
    def tags_indexing(self):
        """Tags for indexing.

        Used in Elasticsearch indexing.
        """
        return [tag.title for tag in self.tags.all()]
Admin classes

This is just trivial. A couple of correspondent admin classes in order to ba able to fill some data.

books/admin.py

from django.contrib import admin

from .models import *


@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    """Book admin."""

    list_display = ('title', 'isbn', 'price', 'publication_date')
    search_fields = ('title',)
    filter_horizontal = ('authors', 'tags',)


@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    """Author admin."""

    list_display = ('name', 'email',)
    search_fields = ('name',)


@admin.register(Publisher)
class PublisherAdmin(admin.ModelAdmin):
    """Publisher admin."""

    list_display = ('name',)
    search_fields = ('name',)


@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    """Tag admin."""

    list_display = ('title',)
    search_fields = ('title',)
Create database tables

For now, just run the migrations to create the database tables.

./manage.py makemigrations books
./manage.py migrate books
Fill in some data

If you have followed the instructions, you should now be able to log into the Django admin and create a dozen of Book/Author/Publisher/Tag records in admin.

http://localhost:8000/admin/books/publisher/
http://localhost:8000/admin/books/author/
http://localhost:8000/admin/books/tag/
http://localhost:8000/admin/books/book/

Once you’ve done that, proceed to the next step.

Sample document

In Elasticsearch, a document is a basic unit of information that can be indexed. For example, you can have a document for a single customer, another document for a single product, and yet another for a single order. This document is expressed in JSON (JavaScript Object Notation) which is an ubiquitous internet data interchange format.

Within an index/type, you can store as many documents as you want. Note that although a document physically resides in an index, a document actually must be indexed/assigned to a type inside an index.

Simply said, you could see an Elasticsearch index as a database and a document as a database table (which makes a Document definition in Elasticsearch DSL similar to a Django Model definition).

Often, complex SQL model structures are flatterned in Elasticsearch indexes/documents. Nested relations are denormalized.

In our example, all 4 models (Author, Publisher, Tag, Book) would be flatterned into a single BookDocument, which would hold all the required information.

Content of the search_indexes/documents/book.py file. Additionally, see the code comments.

Required imports

search_indexes/documents/book.py

from django.conf import settings
from django_elasticsearch_dsl import Document, Index, fields
from elasticsearch_dsl import analyzer

from books.models import Book
Index definition

To separate dev/test/staging/production indexes, the following approach is recommended.

Settings

Note

In the examples below the search_indexes.documents.book and search_indexes.documents.publisher are the pythonic file paths to modules where documents are defined.

settings/base.py

Note

In this example, book and publisher are Elasticsearch index names.

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.book': 'book',
    'search_indexes.documents.publisher': 'publisher',
}

settings/testing.py

Note

In this example, test_book and test_publisher are Elasticsearch index names.

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.book': 'test_book',
    'search_indexes.documents.publisher': 'test_publisher',
}

settings/production.py

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.book': 'prod_book',
    'search_indexes.documents.publisher': 'prod_publisher',
}
Document index

search_indexes/documents/book.py

# Name of the Elasticsearch index
INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

# See Elasticsearch Indices API reference for available settings
INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1
)
Custom analyzers
html_strip = analyzer(
    'html_strip',
    tokenizer="standard",
    filter=["standard", "lowercase", "stop", "snowball"],
    char_filter=["html_strip"]
)
Document definition

search_indexes/documents/book.py

@INDEX.doc_type
class BookDocument(Document):
    """Book Elasticsearch document."""

    id = fields.IntegerField(attr='id')

    title = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    description = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    summary = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    publisher = fields.StringField(
        attr='publisher_indexing',
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    publication_date = fields.DateField()

    state = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    isbn = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    price = fields.FloatField()

    pages = fields.IntegerField()

    stock_count = fields.IntegerField()

    tags = fields.StringField(
        attr='tags_indexing',
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword', multi=True),
            'suggest': fields.CompletionField(multi=True),
        },
        multi=True
    )

    class Meta(object):
        """Meta options."""

        model = Book  # The model associate with this Document
Syncing Django’s database with Elasticsearch indexes

So far, we have a couple of Django models and a single (decentralized) Elasticsearch index/document (Book).

Full database sync

The excellent django-elasticsearch-dsl library makes a good job of keeping the Book index fresh. It makes use of signals, so whenever the Book model is changed, the correspondent BookDocument indexes would be updated.

To simply run the full sync between Django’s database and Elasticsearch, do as follows:

  1. Create Elasticsearch indexes:

    ./manage.py search_index --create -f
    
  2. Sync the data:

    ./manage.py search_index --populate -f
    

However, in case if a Tag, Publisher or Author models change, the Book index would not be automatically updated.

Sample partial sync (using custom signals)

In order to keep indexes fresh, you will have to write a couple of simple lines of code (using Django’s signals). Whenever a change is made to any of the Tag, Publisher or Author models, we’re going to update the correspondent BookDocument index.

Required imports

search_indexes/signals.py

from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver

from django_elasticsearch_dsl.registries import registry
Sample serializer

At this step we’re going to define a serializer to be used in the Django REST framework ViewSet.

Content of the search_indexes/serializers.py file. Additionally, see the code comments.

Required imports

search_indexes/serializers/book.py

import json

from rest_framework import serializers
from django_elasticsearch_dsl_drf.serializers import DocumentSerializer

from .documents import BookDocument
Serializer definition

Simplest way to create a serializer, is to just specify which fields are needed to be serialized and leave it further to the dynamic serializer.

search_indexes/serializers/book.py

class BookDocumentSerializer(DocumentSerializer):
    """Serializer for the Book document."""

    class Meta(object):
        """Meta options."""

        # Specify the correspondent document class
        document = BookDocument

        # List the serializer fields. Note, that the order of the fields
        # is preserved in the ViewSet.
        fields = (
            'id',
            'title',
            'description',
            'summary',
            'publisher',
            'publication_date',
            'state',
            'isbn',
            'price',
            'pages',
            'stock_count',
            'tags',
        )

However, if dynamic serializer doesn’t work for your or you want to customize too many things, you are free to use standard Serializer class of the Django REST framework.

search_indexes/serializers/book.py

class BookDocumentSerializer(serializers.Serializer):
    """Serializer for the Book document."""

    id = serializers.IntegerField(read_only=True)

    title = serializers.CharField(read_only=True)
    description = serializers.CharField(read_only=True)
    summary = serializers.CharField(read_only=True)

    publisher = serializers.CharField(read_only=True)
    publication_date = serializers.DateField(read_only=True)
    state = serializers.CharField(read_only=True)
    isbn = serializers.CharField(read_only=True)
    price = serializers.FloatField(read_only=True)
    pages = serializers.IntegerField(read_only=True)
    stock_count = serializers.IntegerField(read_only=True)
    tags = serializers.SerializerMethodField()

    class Meta(object):
        """Meta options."""

        # List the serializer fields. Note, that the order of the fields
        # is preserved in the ViewSet.
        fields = (
            'id',
            'title',
            'description',
            'summary',
            'publisher',
            'publication_date',
            'state',
            'isbn',
            'price',
            'pages',
            'stock_count',
            'tags',
        )

    def get_tags(self, obj):
        """Get tags."""
        if obj.tags:
            return list(obj.tags)
        else:
            return []
ViewSet definition

At this step, we’re going to define Django REST framework ViewSets.

Content of the search_indexes/viewsets.py file. Additionally, see the code comments.

Required imports

search_indexes/viewsets/book.py

from django_elasticsearch_dsl_drf.constants import (
    LOOKUP_FILTER_TERMS,
    LOOKUP_FILTER_RANGE,
    LOOKUP_FILTER_PREFIX,
    LOOKUP_FILTER_WILDCARD,
    LOOKUP_QUERY_IN,
    LOOKUP_QUERY_GT,
    LOOKUP_QUERY_GTE,
    LOOKUP_QUERY_LT,
    LOOKUP_QUERY_LTE,
    LOOKUP_QUERY_EXCLUDE,
)
from django_elasticsearch_dsl_drf.filter_backends import (
    FilteringFilterBackend,
    IdsFilterBackend,
    OrderingFilterBackend,
    DefaultOrderingFilterBackend,
    SearchFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import BaseDocumentViewSet
from django_elasticsearch_dsl_drf.pagination import PageNumberPagination

from .documents import BookDocument, PublisherDocument
from .serializers import BookDocumentSerializer
ViewSet definition

search_indexes/viewsets/book.py

class BookDocumentView(BaseDocumentViewSet):
    """The BookDocument view."""

    document = BookDocument
    serializer_class = BookDocumentSerializer
    pagination_class = PageNumberPagination
    lookup_field = 'id'
    filter_backends = [
        FilteringFilterBackend,
        IdsFilterBackend,
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        SearchFilterBackend,
    ]
    # Define search fields
    search_fields = (
        'title',
        'description',
        'summary',
    )
    # Define filter fields
    filter_fields = {
        'id': {
            'field': 'id',
            # Note, that we limit the lookups of id field in this example,
            # to `range`, `in`, `gt`, `gte`, `lt` and `lte` filters.
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
            ],
        },
        'title': 'title.raw',
        'publisher': 'publisher.raw',
        'publication_date': 'publication_date',
        'state': 'state.raw',
        'isbn': 'isbn.raw',
        'price': {
            'field': 'price.raw',
            # Note, that we limit the lookups of `price` field in this
            # example, to `range`, `gt`, `gte`, `lt` and `lte` filters.
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
            ],
        },
        'pages': {
            'field': 'pages',
            # Note, that we limit the lookups of `pages` field in this
            # example, to `range`, `gt`, `gte`, `lt` and `lte` filters.
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
            ],
        },
        'stock_count': {
            'field': 'stock_count',
            # Note, that we limit the lookups of `stock_count` field in
            # this example, to `range`, `gt`, `gte`, `lt` and `lte`
            # filters.
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
            ],
        },
        'tags': {
            'field': 'tags',
            # Note, that we limit the lookups of `tags` field in
            # this example, to `terms, `prefix`, `wildcard`, `in` and
            # `exclude` filters.
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'tags.raw': {
            'field': 'tags.raw',
            # Note, that we limit the lookups of `tags.raw` field in
            # this example, to `terms, `prefix`, `wildcard`, `in` and
            # `exclude` filters.
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
    }
    # Define ordering fields
    ordering_fields = {
        'id': 'id',
        'title': 'title.raw',
        'price': 'price.raw',
        'state': 'state.raw',
        'publication_date': 'publication_date',
    }
    # Specify default ordering
    ordering = ('id', 'title', 'price',)
URLs

At this step, we’re going to define url patterns.

Content of the search_indexes/urls.py file. Additionally, see the code comments.

Required imports

search_indexes/urls.py

from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter

from .views import BookDocumentView
Router definition

search_indexes/urls.py

router = DefaultRouter()
books = router.register(r'books',
                        BookDocumentView,
                        basename='bookdocument')
URL patterns

search_indexes/urls.py

urlpatterns = [
    url(r'^', include(router.urls)),
]
Check what you’ve done so far

At this point, you are one step away from a working example of integrating Elasticsearch DSL with Django.

URLs

If you didn’t add the urls of the search_indexes example application to your project’s global url patterns, make sure to do it now.

from django.conf.urls import include, url
from search_indexes import urls as search_index_urls

urlpatterns = [
    # ...
    # Search URLs
    url(r'^search/', include(search_index_urls)),
    # ...
]
Test in browser

Open the following URL in your browser.

http://localhost:8000/search/books/

Perform a number of lookups:

http://localhost:8001/search/books/?ids=54|55|56
http://localhost:8001/search/books/?summary__contains=photography
http://localhost:8001/search/books/?tags__contains=ython
http://localhost:8001/search/books/?state=published
http://localhost:8001/search/books/?pages__gt=10&pages__lt=30

Development and debugging

Profiling tools

Looking for profiling tools for Elasticsearch?

Try django-elasticsearch-debug-toolbar package. It’s implemented as a panel for the well known Django Debug Toolbar and gives you full insights on what’s happening on the side of Elasticsearch.

Installation
pip install django-debug-toolbar
pip install django-elasticsearch-debug-toolbar
Configuration

Change your development settings in the following way:

settings/dev.py

MIDDLEWARE += (
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'debug_toolbar_force.middleware.ForceDebugToolbarMiddleware',
)

INSTALLED_APPS += (
    'debug_toolbar',
    'elastic_panel',
)

DEBUG_TOOLBAR_CONFIG = {
    'INTERCEPT_REDIRECTS': False,
}

DEBUG_TOOLBAR_PANELS = (
    # Defaults
    'debug_toolbar.panels.versions.VersionsPanel',
    'debug_toolbar.panels.timer.TimerPanel',
    'debug_toolbar.panels.settings.SettingsPanel',
    'debug_toolbar.panels.headers.HeadersPanel',
    'debug_toolbar.panels.request.RequestPanel',
    'debug_toolbar.panels.sql.SQLPanel',
    'debug_toolbar.panels.staticfiles.StaticFilesPanel',
    'debug_toolbar.panels.templates.TemplatesPanel',
    'debug_toolbar.panels.cache.CachePanel',
    'debug_toolbar.panels.signals.SignalsPanel',
    'debug_toolbar.panels.logging.LoggingPanel',
    'debug_toolbar.panels.redirects.RedirectsPanel',
    # Additional
    'elastic_panel.panel.ElasticDebugPanel',
)
Debugging

Although (the unbeatable) Kibana is strongly recommended for data analyses, there are other good tools worth mentioning. One of them is elasticsearch-head Elasticsearch 2.x plugin or a correspondent Chrome extension of the same plugin. You may find it very useful for quick data preview or testing Elasticsearch queries.

Filter usage examples

Example usage of filtering backends.

Contents:

Filtering

Supported lookups
Native

The following native (to Elasticsearch) filters/lookups are implemented:

term

Find documents which contain the exact term specified in the field specified.

http://127.0.0.1:8080/search/books/?tags__term=education&tags__term=economy
terms

Find documents which contain any of the exact terms specified in the field specified. Note, that multiple values are separated with double underscores __.

http://localhost:8000/api/articles/?id=1&id=2&id=3
http://localhost:8000/api/articles/?id__terms=1__2__3
range

Find documents where the field specified contains values (dates, numbers, or strings) in the range specified.

From, to

http://localhost:8000/api/users/?age__range=16__67

From, to, boost

http://localhost:8000/api/users/?age__range=16__67__2.0
exists

Find documents where the field specified contains any non-null value.

http://localhost:8000/api/articles/?tags__exists=true
prefix

Find documents where the field specified contains terms which begin with the exact prefix specified.

http://localhost:8000/api/articles/?tags__prefix=bio
wildcard

Find documents where the field specified contains terms which match the pattern specified, where the pattern supports single character wildcards (?) and multi-character wildcards (*)

http://localhost:8000/api/articles/?title__wildcard=*elusional*

Should match: delusional insanity.

ids

Find documents with the specified type and IDs.

http://localhost:8000/api/articles/?ids=68__64__58
http://localhost:8000/api/articles/?ids=68&ids=64&ids=58
Functional

The following functional (non-native to Elasticsearch, but common in Django) filters/lookups are implemented:

contains

Case-insensitive containment test.

http://localhost:8000/api/articles/?state__contains=lishe

Should match: published, not published, needs polishing.

in

In a given list.

http://localhost:8000/api/articles/?id__in=1__2__3
gt

Greater than.

http://localhost:8000/api/users/?id__gt=10
gte

Greater than or equal to.

http://localhost:8000/api/users/?id__gte=10
lt

Less than.

http://localhost:8000/api/users/?id__lt=10
lte

Less than or equal to.

http://localhost:8000/api/users/?id__lte=10
startswith

Case-sensitive starts-with.

Should match: biography, bio mechanics

endswith

Case-sensitive ends-with.

http://localhost:8000/api/articles/?state__endswith=lished

Should match: published, not published.

isnull

Takes either True or False.

True

http://localhost:8000/api/articles/?null_field__isnull=true

False

http://localhost:8000/api/articles/?tags__isnull=false
exclude

Returns a new query set of containing objects that do not match the given lookup parameters.

http://localhost:8000/api/articles/?tags__exclude=children
http://localhost:8000/api/articles/?tags__exclude=children__python

Search backends

Compound search filter backend

Compound search filter backend aims to replace old style SearchFilterBackend.

Sample view
from django_elasticsearch_dsl_drf.filter_backends import (
    DefaultOrderingFilterBackend,
    CompoundSearchFilterBackend,
    OrderingFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

from .documents import BookDocument
from .serializers import BookDocumentSerializer

class BookCompoundSearchBackendDocumentViewSet(DocumentViewSet):

    document = BookDocument
    serializer_class = BookDocumentSerializer
    lookup_field = 'id'

    filter_backends = [
        # ...
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        CompoundSearchFilterBackend,
        # ...
    ]

    multi_match_search_fields = (
        'title',
        'description',
        'summary',
    )

    ordering = ('_score', 'id', 'title', 'price',)
Sample request
http://localhost:8000/search/books-compound-search-backend/?search=enim
Generated query
{
  "from": 0,
  "sort": [
    "id",
    "title",
    "price"
  ],
  "size": 23,
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": {
              "query": "enim"
            }
          }
        },
        {
          "match": {
            "description": {
              "query": "enim"
            }
          }
        },
        {
          "match": {
            "summary": {
              "query": "enim"
            }
          }
        }
      ]
    }
  }
}

Multi match search filter backend

Document and serializer definition are trivial (there are lots of examples in other sections).

Sample view
from django_elasticsearch_dsl_drf.filter_backends import (
    DefaultOrderingFilterBackend,
    MultiMatchSearchFilterBackend,
    OrderingFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

from .documents import BookDocument
from .serializers import BookDocumentSerializer


class BookMultiMatchSearchFilterBackendDocumentViewSet(DocumentViewSet):

    document = BookDocument
    serializer_class = BookDocumentSerializer
    lookup_field = 'id'

    filter_backends = [
        # ...
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        MultiMatchSearchFilterBackend,
        # ...
    ]

    multi_match_search_fields = {
        'title': {'boost': 4},
        'summary': {'boost': 2},
        'description': None,
    }

    ordering = ('_score', 'id', 'title', 'price',)
Sample request

Note

Multiple search params (search_multi_match) are not supported. Even if you provide multiple search params, the first one would be picked, having the rest simply ignored.

http://localhost:8000/search/books-multi-match-search-backend/?search_multi_match=debitis%20enim
Generated query
{
  "from": 0,
  "query": {
    "multi_match": {
      "query": "debitis enim",
      "fields": [
        "summary^2",
        "description",
        "title^4"
      ]
    }
  },
  "size": 38,
  "sort": [
    "_score",
    "id",
    "title",
    "price"
  ]
}
Options

All standard multi match query options are available/tunable with help of multi_match_options view property.

Selective list of available options:

  • operator
  • type
  • analyzer
  • tie_breaker
Type options

See the Elasticsearch docs for detailed explanation.

  • best_fields
  • most_fields
  • cross_fields
  • phrase
  • phrase_prefix

Example

class BookMultiMatchSearchFilterBackendDocumentViewSet(DocumentViewSet):

    # ...

    multi_match_options = {
        'type': 'phrase'
    }
Operator options

Can be either and or or.

Simple query string filter backend

Document and serializer definition are trivial (there are lots of examples in other sections).

Sample view
from django_elasticsearch_dsl_drf.filter_backends import (
    DefaultOrderingFilterBackend,
    SimpleQueryStringSearchFilterBackend,
    OrderingFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

from .documents import BookDocument
from .serializers import BookDocumentSerializer


class BookSimpleQueryStringSearchFilterBackendDocumentViewSet(DocumentViewSet):

    document = BookDocument
    serializer_class = BookDocumentSerializer
    lookup_field = 'id'

    filter_backends = [
        # ...
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        SimpleQueryStringSearchFilterBackend,
        # ...
    ]

    simple_query_string_search_fields = {
        'title': {'boost': 4},
        'summary': {'boost': 2},
        'description': None,
    }

    ordering = ('_score', 'id', 'title', 'price',)
Sample request 1

Note

Multiple search params (search_simple_query_string) are not supported. Even if you provide multiple search params, the first one would be picked, having the rest simply ignored.

http://localhost:8000/search/books-simple-query-string-search-backend/?search_simple_query_string="chapter%20II"%20%2Bfender
Generated query 1
{
  "query": {
    "simple_query_string": {
      "query": "\"chapter II\" +fender",
      "default_operator": "and",
      "fields": [
        "title",
        "description",
        "summary"
      ]
    }
  },
  "sort": [
    "_score",
    "id",
    "title",
    "price"
  ],
  "from": 0,
  "size": 1
}
Sample request 2

Note

Multiple search params (search_simple_query_string) are not supported. Even if you provide multiple search params, the first one would be picked, having the rest simply ignored.

http://localhost:8000/search/books-simple-query-string-search-backend/?search_simple_query_string="chapter%20II"%20%2B(shutting%20|%20fender)
Generated query 2
{
  "query": {
    "simple_query_string": {
      "query": "\"chapter II\" +(shutting | fender)",
      "default_operator": "and",
      "fields": [
        "title",
        "description",
        "summary"
      ]
    }
  },
  "sort": [
    "_score",
    "id",
    "title",
    "price"
  ],
  "from": 0,
  "size": 2
}
Sample request 3

Note

Multiple search params (search_simple_query_string) are not supported. Even if you provide multiple search params, the first one would be picked, having the rest simply ignored.

http://localhost:8000/search/books-simple-query-string-search-backend/?search_simple_query_string=%22Pool%20of%20Tears%22%20-considering
Generated query 3
{
  "query": {
    "simple_query_string": {
      "query": "\"Pool of Tears\" -considering",
      "default_operator": "and",
      "fields": [
        "title",
        "description",
        "summary"
      ]
    }
  },
  "sort": [
    "_score",
    "id",
    "title",
    "price"
  ],
  "from": 0,
  "size": 1
}
Options

All standard multi match query options are available/tunable with help of simple_query_string_options view property.

Selective list of available options:

  • default_operator
Default Operator options

Can be either and or or.

Example

class BookSimpleQueryStringSearchFilterBackendDocumentViewSet(DocumentViewSet):

    # ...

    simple_query_string_options = {
        "default_operator": "and",
    }

Basic usage examples

Basic Django REST framework integration example

See the example project for sample models/views/serializers.

Contents:

Example app

Sample models

books/models/publisher.py

class Publisher(models.Model):
    """Publisher."""

    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()
    latitude = models.DecimalField(null=True,
                               blank=True,
                               decimal_places=15,
                               max_digits=19,
                               default=0)
    longitude = models.DecimalField(null=True,
                                    blank=True,
                                    decimal_places=15,
                                    max_digits=19,
                                    default=0)

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name

    @property
    def location_field_indexing(self):
        """Location for indexing.

        Used in Elasticsearch indexing/tests of `geo_distance` native filter.
        """
        return {
            'lat': self.latitude,
            'lon': self.longitude,
        }
Sample document

search_indexes/documents/publisher.py

from django_elasticsearch_dsl import Document, Index, fields
from elasticsearch_dsl import analyzer

from books.models import Publisher

# Name of the Elasticsearch index
PUBLISHER_INDEX = Index('publisher')
# See Elasticsearch Indices API reference for available settings
PUBLISHER_INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1
)


@PUBLISHER_INDEX.doc_type
class PublisherDocument(Document):
    """Publisher Elasticsearch document."""

    id = fields.IntegerField(attr='id')

    name = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )
    info = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )
    address = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )
    city = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )
    state_province = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )
    country = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )
    website = fields.StringField()

    # Location
    location = fields.GeoPointField(attr='location_field_indexing')

    class Meta(object):
        """Meta options."""

        model = Publisher  # The model associate with this Document
Sample serializer

search_indexes/serializers/book.py

import json

from django_elasticsearch_dsl_drf.serializers import DocumentSerializer

class PublisherDocumentSerializer(DocumentSerializer):
    """Serializer for Publisher document."""

    location = serializers.SerializerMethodField()

    class Meta(object):
        """Meta options."""

        # Note, that since we're using a dynamic serializer,
        # we only have to declare fields that we want to be shown. If
        # somehow, dynamic serializer doesn't work for you, either extend
        # or declare your serializer explicitly.
        fields = (
            'id',
            'name',
            'info',
            'address',
            'city',
            'state_province',
            'country',
            'website',
        )

    def get_location(self, obj):
    """Represent location value."""
    try:
        return obj.location.to_dict()
    except:
        return {}
Sample view

search_indexes/views/publisher.py

from django_elasticsearch_dsl_drf.constants import (
    LOOKUP_FILTER_GEO_DISTANCE,
)
from django_elasticsearch_dsl_drf.filter_backends import (
    FilteringFilterBackend,
    OrderingFilterBackend,
    SearchFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

# Example app models
from search_indexes.documents.publisher import PublisherDocument
from search_indxes.serializers import PublisherDocumentSerializer

class PublisherDocumentView(DocumentViewSet):
    """The PublisherDocument view."""

    document = PublisherDocument
    serializer_class = PublisherDocumentSerializer
    lookup_field = 'id'
    filter_backends = [
        FilteringFilterBackend,
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        SearchFilterBackend,
    ]
    # Define search fields
    search_fields = (
        'name',
        'info',
        'address',
        'city',
        'state_province',
        'country',
    )
    # Define filtering fields
    filter_fields = {
        'id': None,
        'name': 'name.raw',
        'city': 'city.raw',
        'state_province': 'state_province.raw',
        'country': 'country.raw',
    }
    # Define ordering fields
    ordering_fields = {
        'id': None,
        'name': None,
        'city': None,
        'country': None,
    }
    # Specify default ordering
    ordering = ('id', 'name',)
    # Define geo-spatial filtering fields
    geo_spatial_filter_fields = {
        'location': {
            'lookups': [
                LOOKUP_FILTER_GEO_DISTANCE,
            ],
        },
    }
Usage example

Considering samples above, you should be able to perform the search, sorting and filtering actions described below.

Sample queries
Filtering

Let’s assume we have a number of Publisher documents with in cities (Yerevan, Groningen, Amsterdam, London).

Multiple filter terms are joined with AND.

Filter documents by single field

Filter documents by field (city) “yerevan”.

http://127.0.0.1:8080/search/publisher/?city=yerevan

Filter documents by multiple fields

Filter documents by city “Yerevan” and “Groningen”.

http://127.0.0.1:8080/search/publisher/?city__in=yerevan__groningen

Filter document by a single field

Filter documents by (field country) “Armenia”.

http://127.0.0.1:8080/search/publisher/?country=armenia

Filter documents by multiple fields

Filter documents by multiple fields (field city) “Yerevan” and “Amsterdam” with use of functional in query filter.

http://127.0.0.1:8080/search/publisher/?city__in=yerevan__amsterdam

You can achieve the same effect by specifying multiple filters (city) “Yerevan” and “Amsterdam”. Note, that in this case multiple filter terms are joined with OR.

http://127.0.0.1:8080/search/publisher/?city=yerevan&city=amsterdam

If you want the same as above, but joined with AND, add __term to each lookup.

http://127.0.0.1:8080/search/publisher/?city__term=education&city__term=economy

Filter documents by a word part of a single field

Filter documents by a part word part in single field (city) “ondon”.

http://127.0.0.1:8080/search/publisher/?city__wildcard=*ondon

Geo-distance filtering

Filter documents by radius of 100000km from the given location.

http://127.0.0.1:8000/search/publishers/?location__geo_distance=100000km__12.04__-63.93
Ordering

The - prefix means ordering should be descending.

Order documents by field (ascending)

Filter documents by field city (ascending).

http://127.0.0.1:8080/search/publisher/?search=country:armenia&ordering=city

Order documents by field (descending)

Filter documents by field country (descending).

http://127.0.0.1:8080/search/publisher/?ordering=-country

Order documents by multiple fields

If you want to order by multiple fields, use multiple ordering query params. In the example below, documents would be ordered first by field country (descending), then by field city (ascending).

http://127.0.0.1:8080/search/publisher/?ordering=-country&ordering=city

Advanced usage examples

Advanced Django REST framework integration examples.

See the example project for sample models/views/serializers.

Contents:

Example app

Sample models

books/models/publisher.py

import json

from django.conf import settings
from django.db import models
from django.utils.translation import ugettext, ugettext_lazy as _

from six import python_2_unicode_compatible

BOOK_PUBLISHING_STATUS_PUBLISHED = 'published'
BOOK_PUBLISHING_STATUS_NOT_PUBLISHED = 'not_published'
BOOK_PUBLISHING_STATUS_IN_PROGRESS = 'in_progress'
BOOK_PUBLISHING_STATUS_CANCELLED = 'cancelled'
BOOK_PUBLISHING_STATUS_REJECTED = 'rejected'
BOOK_PUBLISHING_STATUS_CHOICES = (
    (BOOK_PUBLISHING_STATUS_PUBLISHED, "Published"),
    (BOOK_PUBLISHING_STATUS_NOT_PUBLISHED, "Not published"),
    (BOOK_PUBLISHING_STATUS_IN_PROGRESS, "In progress"),
    (BOOK_PUBLISHING_STATUS_CANCELLED, "Cancelled"),
    (BOOK_PUBLISHING_STATUS_REJECTED, "Rejected"),
)
BOOK_PUBLISHING_STATUS_DEFAULT = BOOK_PUBLISHING_STATUS_PUBLISHED


@python_2_unicode_compatible
class Publisher(models.Model):
    """Publisher."""

    name = models.CharField(max_length=30)
    info = models.TextField(null=True, blank=True)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()
    latitude = models.DecimalField(null=True,
                               blank=True,
                               decimal_places=15,
                               max_digits=19,
                               default=0)
    longitude = models.DecimalField(null=True,
                                    blank=True,
                                    decimal_places=15,
                                    max_digits=19,
                                    default=0)

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name

    @property
    def location_field_indexing(self):
        """Location for indexing.

        Used in Elasticsearch indexing/tests of `geo_distance` native filter.
        """
        return {
            'lat': self.latitude,
            'lon': self.longitude,
        }

books/models/author.py

@python_2_unicode_compatible
class Author(models.Model):
    """Author."""

    salutation = models.CharField(max_length=10)
    name = models.CharField(max_length=200)
    email = models.EmailField()
    headshot = models.ImageField(upload_to='authors', null=True, blank=True)

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name

books/models/tag.py

class Tag(models.Model):
    """Simple tag model."""

    title = models.CharField(max_length=255, unique=True)

    class Meta(object):
        """Meta options."""

        verbose_name = _("Tag")
        verbose_name_plural = _("Tags")

    def __str__(self):
        return self.title

books/models/book.py

@python_2_unicode_compatible
class Book(models.Model):
    """Book."""

    title = models.CharField(max_length=100)
    description = models.TextField(null=True, blank=True)
    summary = models.TextField(null=True, blank=True)
    authors = models.ManyToManyField('books.Author', related_name='books')
    publisher = models.ForeignKey(Publisher, related_name='books')
    publication_date = models.DateField()
    state = models.CharField(max_length=100,
                             choices=BOOK_PUBLISHING_STATUS_CHOICES,
                             default=BOOK_PUBLISHING_STATUS_DEFAULT)
    isbn = models.CharField(max_length=100, unique=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    pages = models.PositiveIntegerField(default=200)
    stock_count = models.PositiveIntegerField(default=30)
    tags = models.ManyToManyField('books.Tag',
                                  related_name='books',
                                  blank=True)

    class Meta(object):
        """Meta options."""

        ordering = ["isbn"]

    def __str__(self):
        return self.title

    @property
    def publisher_indexing(self):
        """Publisher for indexing.

        Used in Elasticsearch indexing.
        """
        if self.publisher is not None:
            return self.publisher.name

    @property
    def tags_indexing(self):
        """Tags for indexing.

        Used in Elasticsearch indexing.
        """
        return [tag.title for tag in self.tags.all()]
Sample document
Index definition

To separate dev/test/staging/production indexes, the following approach is recommended.

Settings

settings/base.py

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.book': 'book',
    'search_indexes.documents.publisher': 'publisher',
}

settings/testing.py

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.book': 'test_book',
    'search_indexes.documents.publisher': 'test_publisher',
}

settings/production.py

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.book': 'prod_book',
    'search_indexes.documents.publisher': 'prod_publisher',
}
Document index

search_indexes/documents/book.py

from django.conf import settings
from django_elasticsearch_dsl import Document, Index, fields
from elasticsearch_dsl import analyzer

from books.models import Book

# Name of the Elasticsearch index
INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

# See Elasticsearch Indices API reference for available settings
INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1
)

html_strip = analyzer(
    'html_strip',
    tokenizer="standard",
    filter=["standard", "lowercase", "stop", "snowball"],
    char_filter=["html_strip"]
)


@INDEX.doc_type
class BookDocument(Document):
    """Book Elasticsearch document."""

    id = fields.IntegerField(attr='id')

    title = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    description = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    summary = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    publisher = fields.StringField(
        attr='publisher_indexing',
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    publication_date = fields.DateField()

    state = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    isbn = fields.StringField(
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword'),
        }
    )

    price = fields.FloatField()

    pages = fields.IntegerField()

    stock_count = fields.IntegerField()

    tags = fields.StringField(
        attr='tags_indexing',
        analyzer=html_strip,
        fields={
            'raw': fields.StringField(analyzer='keyword', multi=True),
            'suggest': fields.CompletionField(multi=True),
        },
        multi=True
    )

    class Meta(object):
        """Meta options."""

        model = Book  # The model associate with this Document
Sample serializer

search_indexes/serializers/tag.py

import json

from rest_framework import serializers

class TagSerializer(serializers.Serializer):
    """Helper serializer for the Tag field of the Book document."""

    title = serializers.CharField()

    class Meta(object):
        """Meta options."""

        fields = ('title',)
        read_only_fields = ('title',)

search_indexes/serializers/book.py

class BookDocumentSerializer(serializers.Serializer):
    """Serializer for the Book document."""

    id = serializers.SerializerMethodField()

    title = serializers.CharField(read_only=True)
    description = serializers.CharField(read_only=True)
    summary = serializers.CharField(read_only=True)

    publisher = serializers.CharField(read_only=True)
    publication_date = serializers.DateField(read_only=True)
    state = serializers.CharField(read_only=True)
    isbn = serializers.CharField(read_only=True)
    price = serializers.FloatField(read_only=True)
    pages = serializers.IntegerField(read_only=True)
    stock_count = serializers.IntegerField(read_only=True)
    tags = serializers.SerializerMethodField()

    class Meta(object):
        """Meta options."""

        fields = (
            'id',
            'title',
            'description',
            'summary',
            'publisher',
            'publication_date',
            'state',
            'isbn',
            'price',
            'pages',
            'stock_count',
            'tags',
        )
        read_only_fields = fields

    def get_tags(self, obj):
        """Get tags."""
        if obj.tags:
            return list(obj.tags)
        else:
            return []
Sample view

search_indexes/viewsets/book.py

from django_elasticsearch_dsl_drf.constants import (
    LOOKUP_FILTER_TERMS,
    LOOKUP_FILTER_RANGE,
    LOOKUP_FILTER_PREFIX,
    LOOKUP_FILTER_WILDCARD,
    LOOKUP_QUERY_IN,
    LOOKUP_QUERY_EXCLUDE,
)
from django_elasticsearch_dsl_drf.filter_backends import (
    FilteringFilterBackend,
    OrderingFilterBackend,
    DefaultOrderingFilterBackend,
    SearchFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

# Example app models
from search_indexes.documents.book import BookDocument
from search_indxes.serializers import BookDocumentSerializer


class BookDocumentView(DocumentViewSet):
    """The BookDocument view."""

    document = BookDocument
    serializer_class = BookDocumentSerializer
    lookup_field = 'id'
    filter_backends = [
        FilteringFilterBackend,
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        SearchFilterBackend,
    ]
    # Define search fields
    search_fields = (
        'title',
        'summary',
        'description',
    )
    # Define filtering fields
    filter_fields = {
        'id': {
            'field': '_id',
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_IN,
            ],
        },
        'publisher': 'publisher.raw',
        'publication_date': 'publication_date',
        'isbn': 'isbn.raw',
        'tags': {
            'field': 'tags',
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'tags.raw': {
            'field': 'tags.raw',
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
    }
    # Define ordering fields
    ordering_fields = {
        'id': 'id',
        'title': 'title.raw',
        'price': 'price.raw',
        'state': 'state.raw',
        'publication_date': 'publication_date',
    }
    # Specify default ordering
    ordering = ('id', 'title',)
Usage example

Considering samples above, you should be able to perform the search, sorting and filtering actions described below.

Filtering

Let’s assume we have a number of Book documents with the tags (education, politics, economy, biology, climate, environment, internet, technology).

Multiple filter terms are joined with AND.

Filter documents by field

Filter documents by field (state) “published”.

http://127.0.0.1:8080/search/books/?state=published

Filter documents by multiple fields

Filter documents by field (states) “published” and “in_progress”.

http://127.0.0.1:8080/search/books/?state__in=published__in_progress

Filter document by a single field

Filter documents by (field tag) “education”.

http://127.0.0.1:8080/search/books/?tag=education

Filter documents by multiple fields

Filter documents by multiple fields (field tags) “education” and “economy” with use of functional in query filter.

http://127.0.0.1:8080/search/books/?tags__in=education__economy

You can achieve the same effect by specifying multiple fields (tags) “education” and “economy”. Note, that in this case multiple filter terms are joined with OR.

http://127.0.0.1:8080/search/books/?tags=education&tags=economy

If you want the same as above, but joined with AND, add __term to each lookup.

http://127.0.0.1:8080/search/books/?tags__term=education&tags__term=economy

Filter documents by a word part of a single field

Filter documents by a part word part in single field (tags). Word part should match both “technology” and “biology”.

http://127.0.0.1:8080/search/books/?tags__wildcard=*logy
Ordering

The - prefix means ordering should be descending.

Order documents by field (ascending)

Order documents by field price (ascending).

http://127.0.0.1:8080/search/books/?search=title:lorem&ordering=price

Order documents by field (descending)

Order documents by field price (descending).

http://127.0.0.1:8080/search/books/?search=title:lorem&ordering=-price

Order documents by multiple fields

If you want to order by multiple fields, use multiple ordering query params. In the example below, documents would be ordered first by field publication_date (descending), then by field price (ascending).

http://127.0.0.1:8080/search/books/?search=title:lorem&ordering=-publication_date&ordering=price
Ids filter

Filters documents that only have the provided ids.

http://127.0.0.1:8000/api/articles/?ids=68__64__58

Or, alternatively:

http://127.0.0.1:8000/api/articles/?ids=68&ids=64&ids=58
Post-filter

The post_filter is very similar to the common filter. The only difference is that it doesn’t affect facets. So, whatever post-filters applied, the numbers in facets will remain intact.

Sample view

Note

Note the PostFilterFilteringFilterBackend and post_filter_fields usage.

search_indexes/viewsets/book.py

# ...

from django_elasticsearch_dsl_drf.filter_backends import (
    # ...
    PostFilterFilteringFilterBackend,
)

# ...

class BookDocumentView(DocumentViewSet):
    """The BookDocument view."""

    document = BookDocument
    serializer_class = BookDocumentSerializer
    lookup_field = 'id'
    filter_backends = [
        FilteringFilterBackend,
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        SearchFilterBackend,
        PostFilterFilteringFilterBackend,
    ]
    # Define search fields
    search_fields = (
        'title',
        'summary',
        'description',
    )
    # Define filtering fields
    filter_fields = {
        'id': {
            'field': '_id',
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_IN,
            ],
        },
        'publisher': 'publisher.raw',
        'publication_date': 'publication_date',
        'isbn': 'isbn.raw',
        'tags': {
            'field': 'tags',
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'tags.raw': {
            'field': 'tags.raw',
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
    }
    # Define post-filter filtering fields
    post_filter_fields = {
        'publisher_pf': 'publisher.raw',
        'isbn_pf': 'isbn.raw',
        'state_pf': 'state.raw',
        'tags_pf': {
            'field': 'tags',
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
    }
    # Define ordering fields
    ordering_fields = {
        'id': 'id',
        'title': 'title.raw',
        'price': 'price.raw',
        'state': 'state.raw',
        'publication_date': 'publication_date',
    }
    # Specify default ordering
    ordering = ('id', 'title',)
Sample queries

Filter documents by field

Filter documents by field (state) “published”.

http://127.0.0.1:8080/search/books/?state_pf=published

Filter documents by multiple fields

Filter documents by field (states) “published” and “in_progress”.

http://127.0.0.1:8080/search/books/?state_pf__in=published__in_progress
Geo-spatial features

For testing the boundaries the following online services might be helpful:

Filtering

Geo-distance filtering

Filter documents by radius of 100000km from the given location.

http://localhost:8000/search/publishers/?location__geo_distance=100000km__12.04__-63.93

Geo-polygon filtering

Filter documents that are located in the given polygon.

http://localhost:8000/search/publishers/?location__geo_polygon=40,-70__30,-80__20,-90

Geo-bounding-box filtering

Filter documents that are located in the given bounding box.

http://localhost:8000/search/publishers/?location__geo_bounding_box=44.87,40.07__43.87,41.11
Ordering

Geo-distance ordering

http://localhost:8000/search/publishers/?ordering=location__48.85__2.30__km__plane
Suggestions

The suggest feature suggests similar looking terms based on a provided text by using a suggester.

Note

The SuggesterFilterBackend filter backend can be used in the suggest custom view action/route only. Usages outside of the are suggest action/route are restricted.

There are three options available here: term, phrase and completion.

Note

Suggestion functionality is exclusive. Once you have queried the SuggesterFilterBackend, the latter will transform your current search query into suggestion search query (which is very different). Therefore, always add it as the very last filter backend.

Completion suggesters
Document definition

To make use of suggestions, you should properly index relevant fields of your documents using fields.CompletionField.

search_indexes/documents/publisher.py

from django.conf import settings

from django_elasticsearch_dsl import Document, Index, fields

from books.models import Publisher

# Name of the Elasticsearch index
INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

# See Elasticsearch Indices API reference for available settings
INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1
)


@INDEX.doc_type
class PublisherDocument(Document):
    """Publisher Elasticsearch document."""

    id = fields.IntegerField(attr='id')

    name = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
            'suggest': fields.CompletionField(),
        }
    )

    info = fields.StringField()

    address = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword')
        }
    )

    city = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
            'suggest': fields.CompletionField(),
        }
    )

    state_province = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
            'suggest': fields.CompletionField(),
        }
    )

    country = fields.StringField(
        fields={
            'raw': fields.StringField(analyzer='keyword'),
            'suggest': fields.CompletionField(),
        }
    )

    website = fields.StringField()

    # Location
    location = fields.GeoPointField(attr='location_field_indexing')

    class Meta(object):
        """Meta options."""

        model = Publisher  # The model associate with this Document

After that the name.suggest, city.suggest, state_province.suggest and country.suggest fields would be available for suggestions feature.

Serializer definition

This is how publisher serializer would look like.

search_indexes/serializers/publisher.py

import json

from django_elasticsearch_dsl_drf.serializers import DocumentSerializer

class PublisherDocumentSerializer(DocumentSerializer):
    """Serializer for Publisher document."""

    class Meta(object):
        """Meta options."""

        # Note, that since we're using a dynamic serializer,
        # we only have to declare fields that we want to be shown. If
        # somehow, dynamic serializer doesn't work for you, either extend
        # or declare your serializer explicitly.
        fields = (
            'id',
            'name',
            'info',
            'address',
            'city',
            'state_province',
            'country',
            'website',
        )
ViewSet definition

In order to add suggestions support, we would have to extend our view set in the following way:

search_indexes/viewsets/publisher.py

# ...

from django_elasticsearch_dsl_drf.constants import SUGGESTER_COMPLETION
from django_elasticsearch_dsl_drf.filter_backends import (
    # ...
    SuggesterFilterBackend,
)

# ...

class PublisherDocumentViewSet(DocumentViewSet):
    """The PublisherDocument view."""

    document = PublisherDocument

    # ...

    filter_backends = [
        # ...
        SuggesterFilterBackend,
    ]

    # ...

    # Suggester fields
    suggester_fields = {
        'name_suggest': {
            'field': 'name.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
            'options': {
                'size': 20,  # Override default number of suggestions
            },
        },
        'city_suggest': {
            'field': 'city.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        },
        'state_province_suggest': {
            'field': 'state_province.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        },
        'country_suggest': {
            'field': 'country.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        },
    }

    # Geo-spatial filtering fields
    geo_spatial_filter_fields = {
        'location': {
            'lookups': [
                LOOKUP_FILTER_GEO_DISTANCE,
            ],
        },
    }

In the example below, we show suggestion results (auto-completion) for country field.

Sample requests/responses

Once you have extended your view set with SuggesterFilterBackend functionality, you can make use of the suggest custom action of your view set.

Request

GET http://127.0.0.1:8000/search/publishers/suggest/?country_suggest__completion=Ar

Response

{
    "_shards": {
        "failed": 0,
        "successful": 1,
        "total": 1
    },
    "country_suggest__completion": [
        {
            "options": [
                {
                    "score": 1.0,
                    "text": "Armenia"
                },
                {
                    "score": 1.0,
                    "text": "Argentina"
                }
            ],
            "offset": 0,
            "length": 2,
            "text": "Ar"
        }
    ]
}

You can also have multiple suggesters per request.

Request

GET http://127.0.0.1:8000/search/publishers/suggest/?name_suggest__completion=B&country_suggest__completion=Ar

Response

{
    "_shards": {
        "successful": 1,
        "total": 1,
        "failed": 0
    },
    "country_suggest__completion": [
        {
            "text": "Ar",
            "options": [
                {
                    "score": 1.0,
                    "text": "Armenia"
                },
                {
                    "score": 1.0,
                    "text": "Argentina"
                }
            ],
            "offset": 0,
            "length": 2
        }
    ],
    "name_suggest__completion": [
        {
            "text": "B",
            "options": [
                {
                    "score": 1.0,
                    "text": "Book Works"
                },
                {
                    "score": 1.0,
                    "text": "Brumleve LLC"
                },
                {
                    "score": 1.0,
                    "text": "Booktrope"
                },
                {
                    "score": 1.0,
                    "text": "Borman, Post and Wendt"
                },
                {
                    "score": 1.0,
                    "text": "Book League of America"
                }
            ],
            "offset": 0,
            "length": 1
        }
    ]
}
Suggestions on Array/List field

Suggestions on Array/List fields (typical use case - tags, where Tag model would be a many-to-many relation to a Book model) work almost the same.

Before checking the Sample requests/responses, do have in mind the following:

Sample requests/responses

Once you have extended your view set with SuggesterFilterBackend functionality, you can make use of the suggest custom action of your view set.

Request

GET http://127.0.0.1:8000/search/books/suggest/?tag_suggest__completion=bio

Response

{
    "_shards": {
        "failed": 0,
        "successful": 1,
        "total": 1
    },
    "country_suggest__completion": [
        {
            "options": [
                {
                    "score": 1.0,
                    "text": "Biography"
                },
                {
                    "score": 1.0,
                    "text": "Biology"
                }
            ],
            "offset": 0,
            "length": 2,
            "text": "bio"
        }
    ]
}
Context suggesters

Note, that context suggesters only work for completion (thus, not for term or phrase).

category context

The completion suggester considers all documents in the index, but it is often desirable to serve suggestions filtered and/or boosted by some criteria. For example, you want to suggest song titles filtered by certain artists or you want to boost song titles based on their genre.

In that case, the document definition should be altered as follows:

Document definition

class BookDocument(Document):

    # ...

    title = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
            'suggest_context': fields.CompletionField(
                contexts=[
                    {
                        "name": "tag",
                        "type": "category",
                        # The `path` value shall be pointing to an
                        # existing field of current document, which shall
                        # be used for filtering.
                        "path": "tags.raw",
                    },
                ]
            ),
        }
    )

    # Tags
    tags = StringField(
        attr='tags_indexing',
        analyzer=html_strip,
        fields={
            'raw': KeywordField(multi=True),
            'suggest': fields.CompletionField(multi=True),
        },
        multi=True
    )

    # ...

ViewSet should altered as follows:

ViewSet definition

class BookFrontendDocumentViewSet(DocumentViewSet):

    # ...

    # Suggester fields
    suggester_fields = {
        'title_suggest_context': {
            'field': 'title.suggest_context',
            'default_suggester': SUGGESTER_COMPLETION,
            # We want to be able to filter the completion filter
            # results on the following params: tag, state and publisher.
            # We also want to provide the size value.
            # See the "https://www.elastic.co/guide/en/elasticsearch/
            # reference/6.1/suggester-context.html" for the reference.
            'completion_options': {
                'category_filters': {
                    # The `tag` has been defined as `name` value in the
                    # `suggest_context` of the `BookDocument`.
                    'title_suggest_tag': 'tag',
                },
            },
            'options': {
                'size': 10,  # By default, number of results is 5.
            },
        },
    }

    # ...

And finally we can narrow our suggestions as follows:

Sample request

In the example below we have filtered suggestions by tags “Art” and “Comics” having boosted “Comics” by 2.0.

GET http://localhost:8000/search/books-frontend/suggest/?title_suggest_context=M&title_suggest_tag=Art&title_suggest_tag=Comics__2.0
geo context

Geo context allows to get suggestions within a certain distance from a specified geo location.

In that case, the document definition should be altered as follows:

Document definition

class AddressDocument(Document):

    # ...

    street = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
            'suggest_context': fields.CompletionField(
                contexts=[
                    {
                        "name": "loc",
                        "type": "geo",
                        "path": "location",
                        # You could also optionally add precision value.
                        # However, this is not required and can be
                        # specified in the query during runtime.
                        # "precision": "100km",
                    },
                ],
            ),
        }
    )

    location = fields.GeoPointField(
        attr='location_field_indexing',
    )

    # ...

ViewSet should altered as follows:

ViewSet definition

class BookFrontendDocumentViewSet(DocumentViewSet):

    # ...

    # Suggester fields
    suggester_fields = {
        'street_suggest_context': {
            'field': 'street.suggest_context',
            'default_suggester': SUGGESTER_COMPLETION,
            # We want to be able to filter the completion filter
            # results on the following params: tag, state and publisher.
            # We also want to provide the size value.
            # See the "https://www.elastic.co/guide/en/elasticsearch/
            # reference/6.1/suggester-context.html" for the reference.
            'completion_options': {
                'geo_filters': {
                    'title_suggest_loc': 'loc',
                },
            },
            'options': {
                'size': 10,  # By default, number of results is 5.
            },
        },
    }

    # ...

And finally we can narrow our suggestions as follows:

Sample request

In the example below we have filtered suggestions within 8000km distance from geo-point (-30, -100).

GET http://localhost:8000/search/addresses-frontend/suggest/?street_suggest_context=L&title_suggest_loc=-30__-100__8000km

Same query with boosting (boost value 2.0):

GET http://localhost:8000/search/addresses-frontend/suggest/?street_suggest_context=L&title_suggest_loc=-30__-100__8000km__2.0
Term and Phrase suggestions

While for the completion suggesters to work the CompletionField shall be used, the term and phrase suggesters work on common text fields.

Document definition

search_indexes/documents/book.py

from django.conf import settings

from django_elasticsearch_dsl import Document, Index, fields

from books.models import Book

# Name of the Elasticsearch index
INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

# See Elasticsearch Indices API reference for available settings
INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1
)

@INDEX.doc_type
class BookDocument(Document):
    """Book Elasticsearch document."""
    # ID
    id = fields.IntegerField(attr='id')

    title = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
        }
    )

    description = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
        }
    )

    summary = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField()
        }
    )

    # Publisher
    publisher = StringField(
        attr='publisher_indexing',
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
        }
    )

    # Publication date
    publication_date = fields.DateField()

    # State
    state = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
        }
    )

    # ISBN
    isbn = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
        }
    )

    # Price
    price = fields.FloatField()

    # Pages
    pages = fields.IntegerField()

    # Stock count
    stock_count = fields.IntegerField()

    # Tags
    tags = StringField(
        attr='tags_indexing',
        analyzer=html_strip,
        fields={
            'raw': KeywordField(multi=True),
            'suggest': fields.CompletionField(multi=True),
        },
        multi=True
    )

    null_field = fields.StringField(attr='null_field_indexing')

    class Meta(object):
        """Meta options."""

        model = Book  # The model associate with this Document
ViewSet definition

Note

The suggester filter backends shall come as last ones.

Suggesters for the view are configured in suggester_fields property.

In the example below, the title_suggest is the name of the GET query param which points to the title.suggest field of the BookDocument document. For the title_suggest the allowed suggesters are SUGGESTER_COMPLETION, SUGGESTER_TERM and SUGGESTER_PHRASE.

URL shall be constructed in the following way:

/search/books/suggest/?{QUERY_PARAM}__{SUGGESTER_NAME}={VALUE}

Example for completion suggester:

GET http://127.0.0.1:8000/search/books/suggest/?title_suggest__completion=temp

However, since we have default_suggester defined we can skip the __{SUGGESTER_NAME} part (if we want completion suggester functionality). Thus, it might be written as short as:

GET http://127.0.0.1:8000/search/books/suggest/?title_suggest=temp

Example for term suggester:

GET http://127.0.0.1:8000/search/books/suggest/?title_suggest__term=tmeporus

Example for phrase suggester:

GET http://127.0.0.1:8000/search/books/suggest/?title_suggest__phrase=tmeporus

search_indexes/viewsets/book.py

from django_elasticsearch_dsl_drf.constants import (
    LOOKUP_FILTER_PREFIX,
    LOOKUP_FILTER_RANGE,
    LOOKUP_FILTER_TERMS,
    LOOKUP_FILTER_WILDCARD,
    LOOKUP_QUERY_EXCLUDE,
    LOOKUP_QUERY_GT,
    LOOKUP_QUERY_GTE,
    LOOKUP_QUERY_IN,
    LOOKUP_QUERY_IN,
    LOOKUP_QUERY_ISNULL,
    LOOKUP_QUERY_LT,
    LOOKUP_QUERY_LTE,
    SUGGESTER_COMPLETION,
    SUGGESTER_PHRASE,
    SUGGESTER_TERM,
)
from django_elasticsearch_dsl_drf.filter_backends import (
    # ...
    SuggesterFilterBackend,
)

class BookDocumentViewSet(DocumentViewSet):
    """The BookDocument view."""

    document = BookDocument
    # serializer_class = BookDocumentSerializer
    serializer_class = BookDocumentSimpleSerializer
    lookup_field = 'id'
    filter_backends = [
        FilteringFilterBackend,
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        SearchFilterBackend,
        SuggesterFilterBackend,  # This should be the last backend
    ]
    # Define search fields
    search_fields = (
        'title',
        'description',
        'summary',
    )
    # Define filter fields
    filter_fields = {
        'id': {
            'field': 'id',
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
                LOOKUP_FILTER_TERMS,
            ],
        },
        'title': 'title.raw',
        'publisher': 'publisher.raw',
        'publication_date': 'publication_date',
        'state': 'state.raw',
        'isbn': 'isbn.raw',
        'price': {
            'field': 'price.raw',
            'lookups': [
                LOOKUP_FILTER_RANGE,
            ],
        },
        'pages': {
            'field': 'pages',
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
            ],
        },
        'stock_count': {
            # 'field': 'stock_count',
            'lookups': [
                LOOKUP_FILTER_RANGE,
                LOOKUP_QUERY_GT,
                LOOKUP_QUERY_GTE,
                LOOKUP_QUERY_LT,
                LOOKUP_QUERY_LTE,
            ],
        },
        'tags': {
            'field': 'tags',
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
                LOOKUP_QUERY_ISNULL,
            ],
        },
        'tags.raw': {
            'field': 'tags.raw',
            'lookups': [
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
        },
        # This has been added to test `exists` filter.
        'non_existent_field': 'non_existent_field',
        # This has been added to test `isnull` filter.
        'null_field': 'null_field',
    }
    # Define ordering fields
    ordering_fields = {
        'id': 'id',
        'title': 'title.raw',
        'price': 'price.raw',
        'state': 'state.raw',
        'publication_date': 'publication_date',
    }
    # Specify default ordering
    ordering = ('id', 'title', 'price',)

    # Suggester fields
    suggester_fields = {
        'title_suggest': {
            'field': 'title.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
                SUGGESTER_TERM,
                SUGGESTER_PHRASE,
            ]
            'default_suggester': SUGGESTER_COMPLETION,
            'options': {
                'size': 10,  # Number of suggestions to retrieve.
            },
        },
        'publisher_suggest': 'publisher.suggest',
        'tag_suggest': 'tags.suggest',
        'summary_suggest': 'summary',
    }

Note, that by default the number of suggestions is limited to 5. If you need more suggestions, add ‘options` dictionary with size provided, as show above.

Sample requests/responses

Once you have extended your view set with SuggesterFilterBackend functionality, you can make use of the suggest custom action of your view set.

Let’s considering, that one of our books has the following text in the summary:

Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.
All mimsy were the borogoves
And the mome raths outgrabe.

"Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jubjub bird, and shun
The frumious Bandersnatch!"

He took his vorpal sword in his hand,
Long time the manxome foe he sought --
So rested he by the Tumtum tree,
And stood awhile in thought.
Completion

Request

GET http://127.0.0.1:8000/search/books/suggest/?title_suggest__completion=temp

Response

{
    "_shards": {
        "successful": 1,
        "total": 1,
        "failed": 0
    },
    "title_suggest": [
        {
            "length": 4,
            "text": "temp",
            "options": [
                {
                    "text": "Tempora voluptates distinctio facere ",
                    "_index": "book",
                    "_score": 1.0,
                    "_id": "1000087",
                    "_type": "book_document",
                    "_source": {
                        "description": null,
                        "summary": "Veniam dolores recusandae maxime laborum earum.",
                        "id": 1000087,
                        "state": "cancelled",
                        "authors": [
                            "Jayden van Luyssel",
                            "Yassin van Rooij",
                            "Florian van 't Erve",
                            "Mats van Nimwegen",
                            "Wessel Keltenie"
                        ],
                        "title": "Tempora voluptates distinctio facere."
                    }
                },
                {
                    "text": "Tempore sapiente repellat alias ad corrupti",
                    "_index": "book",
                    "_score": 1.0,
                    "_id": "29",
                    "_type": "book_document"
                    "_source": {
                        "description": null,
                        "summary": "Dolores minus architecto iure fugit qui sed.",
                        "id": 29,
                        "state": "canelled",
                        "authors": [
                            "Wout van Northeim",
                            "Lenn van Vliet-Kuijpers",
                            "Tijs Mulder"
                        ],
                        "title": "Tempore sapiente repellat alias ad."
                    },

                },
                {
                    "text": "Temporibus exercitationem minus expedita",
                    "_index": "book",
                    "_score": 1.0,
                    "_id": "17",
                    "_type": "book_document",
                    "_source": {
                        "description": null,
                        "summary": "A laborum alias voluptates tenetur sapiente modi.",
                        "id": 17,
                        "state": "canelled",
                        "authors": [
                            "Juliette Estey",
                            "Keano de Keijzer",
                            "Koen Scheffers",
                            "Florian van 't Erve",
                            "Tara Oversteeg",
                            "Mats van Nimwegen"
                        ],
                        "title": "Temporibus exercitationem minus expedita."
                    }
                }
            ],
            "offset": 0
        }
    ]
}
Term

Request

GET http://127.0.0.1:8000/search/books/suggest/?summary_suggest__term=tovse

Response

{
    "_shards": {
        "failed": 0,
        "total": 1,
        "successful": 1
    },
    "summary_suggest__term": [
        {
            "text": "tovs",
            "offset": 0,
            "options": [
                {
                    "text": "tove",
                    "score": 0.75,
                    "freq": 1
                },
                {
                    "text": "took",
                    "score": 0.5,
                    "freq": 1
                },
                {
                    "text": "twas",
                    "score": 0.5,
                    "freq": 1
                }
            ],
            "length": 5
        }
    ]
}
Phrase

Request

GET http://127.0.0.1:8000/search/books/suggest/?summary_suggest__phrase=slith%20tovs

Response

{
    "summary_suggest__phrase": [
        {
            "text": "slith tovs",
            "offset": 0,
            "options": [
                {
                    "text": "slithi tov",
                    "score": 0.00083028956
                }
            ],
            "length": 10
        }
    ],
    "_shards": {
        "failed": 0,
        "total": 1,
        "successful": 1
    }
}
Functional suggestions

If native suggestions are not good enough for you, use functional suggesters.

Configuration is very similar to native suggesters.

Document definition

Obviously, different filters require different approaches. For instance, when using functional completion prefix filter, the best approach is to use keyword field of the Elasticsearch. While for match completion, Ngram fields work really well.

The following example indicates Ngram analyzer/filter usage.

search_indexes/documents/book.py

from django.conf import settings
from django_elasticsearch_dsl import Document, Index, fields

from elasticsearch_dsl import analyzer
from elasticsearch_dsl.analysis import token_filter

from books.models import Book

edge_ngram_completion_filter = token_filter(
    'edge_ngram_completion_filter',
    type="edge_ngram",
    min_gram=1,
    max_gram=20
)


edge_ngram_completion = analyzer(
    "edge_ngram_completion",
    tokenizer="standard",
    filter=["lowercase", edge_ngram_completion_filter]
)

INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

# See Elasticsearch Indices API reference for available settings
INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1
)

@INDEX.doc_type
class BookDocument(Document):
    """Book Elasticsearch document."""

    # In different parts of the code different fields are used. There are
    # a couple of use cases: (1) more-like-this functionality, where `title`,
    # `description` and `summary` fields are used, (2) search and filtering
    # functionality where all of the fields are used.

    # ID
    id = fields.IntegerField(attr='id')

    # ********************************************************************
    # *********************** Main data fields for search ****************
    # ********************************************************************

    title = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
            'edge_ngram_completion': StringField(
                analyzer=edge_ngram_completion
            ),
        }
    )

    # ...

    class Meta(object):
        """Meta options."""

        model = Book  # The model associate with this Document
ViewSet definition

Note

The suggester filter backends shall come as last ones.

Functional suggesters for the view are configured in functional_suggester_fields property.

In the example below, the title_suggest is the name of the GET query param which points to the title.raw field of the BookDocument document. For the title_suggest the allowed suggester is FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX. For Ngram match we have the title_suggest_match field, which points to title.edge_ngram_completion field of the same document. For title_suggest_match the allowed suggester is FUNCTIONAL_SUGGESTER_COMPLETION_MATCH.

URL shall be constructed in the following way:

/search/books/functional_suggest/?{QUERY_PARAM}__{SUGGESTER_NAME}={VALUE}

Example for completion_prefix suggester:

GET http://localhost:8000/search/books/functional_suggest/?title_suggest_prefix__completion_prefix=Temp

However, since we have default_suggester defined we can skip the __{SUGGESTER_NAME} part (if we want completion_prefix suggester functionality). Thus, it might be written as short as:

GET http://localhost:8000/search/books/functional_suggest/?title_suggest_prefix=Temp

Example for completion_match suggester:

GET http://localhost:8000/search/books/functional_suggest/?title_suggest_match__completion_match=Temp

However, since we have default_suggester defined we can skip the __{SUGGESTER_NAME} part (if we want completion_match suggester functionality). Thus, it might be written as short as:

GET http://localhost:8000/search/books/functional_suggest/?title_suggest_match=Temp

search_indexes/viewsets/book.py

from django_elasticsearch_dsl_drf.constants import (
    # ...
    FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
    FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
)
from django_elasticsearch_dsl_drf.filter_backends import (
    # ...
    SuggesterFilterBackend,
)

class BookDocumentViewSet(DocumentViewSet):
    """The BookDocument view."""

    document = BookDocument
    serializer_class = BookDocumentSerializer
    lookup_field = 'id'
    filter_backends = [
        FilteringFilterBackend,
        IdsFilterBackend,
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        SearchFilterBackend,
        FacetedSearchFilterBackend,
        HighlightBackend,
        FunctionalSuggesterFilterBackend,  # This should come as last
    ]

    # ...

    # Functional suggester fields
    functional_suggester_fields = {
        'title_suggest': {
            'field': 'title.raw',
            'suggesters': [
                FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
            ],
            'default_suggester': FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
            'options': {
                'size': 25,
                'from': 0,
            }
        },
        'title_suggest_match': {
            'field': 'title.edge_ngram_completion',
            'suggesters': [FUNCTIONAL_SUGGESTER_COMPLETION_MATCH],
            'default_suggester': FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
        }
    }

Note

Note, that in functional_suggester_fields['title_suggest']['options'] there are two params: size and from. They control the query size and the offset of the generated functional suggest query.

Highlighting

Highlighters enable you to get highlighted snippets from one or more fields in your search results so you can show users where the query matches are.

ViewSet definition

from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
from django_elasticsearch_dsl_drf.filter_backends import (
    # ...
    HighlightBackend,
)

from ..documents import BookDocument
from ..serializers import BookDocumentSimpleSerializer


class BookDocumentViewSet(BaseDocumentViewSet):
"""The BookDocument view."""

    document = BookDocument
    # serializer_class = BookDocumentSerializer
    serializer_class = BookDocumentSimpleSerializer
    lookup_field = 'id'
    filter_backends = [
        # ...
        HighlightBackend,
    ]

    # ...

    # Define highlight fields
    highlight_fields = {
        'title': {
            'enabled': True,
            'options': {
                'pre_tags': ["<b>"],
                'post_tags': ["</b>"],
            }
        },
        'summary': {
            'options': {
                'fragment_size': 50,
                'number_of_fragments': 3
            }
        },
        'description': {},
    }

    # ...

Request

GET http://127.0.0.1:8000/search/books/?search=optimisation&highlight=title&highlight=summary

Response

{
    "count": 1,
    "next": null,
    "previous": null,
    "facets": {
        "_filter_publisher": {
            "publisher": {
                "buckets": [
                    {
                        "key": "Self published",
                        "doc_count": 1
                    }
                ],
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0
            },
            "doc_count": 1
        }
    },
    "results": [
        {
            "id": 999999,
            "title": "Performance optimisation",
            "description": null,
            "summary": "Ad animi adipisci libero facilis iure totam
                        impedit. Facilis maiores quae qui magnam dolores.
                        Veritatis quia amet porro voluptates iure quod
                        impedit. Dolor voluptatibus maiores at libero
                        magnam.",
            "authors": [
                "Artur Barseghyan"
            ],
            "publisher": "Self published",
            "publication_date": "1981-04-29",
            "state": "cancelled",
            "isbn": "978-1-7372176-0-2",
            "price": 40.51,
            "pages": 162,
            "stock_count": 30,
            "tags": [
                "Guide",
                "Poetry",
                "Fantasy"
            ],
            "highlight": {
                "title": [
                    "Performance <b>optimisation</b>"
                ]
            },
            "null_field": null
        }
    ]
}

Nested fields usage examples

Advanced Django REST framework integration examples with object/nested fields.

See the example project for sample models/views/serializers.

Contents:

Example app

Sample models

books/models/continent.py

from django.db import models

from six import python_2_unicode_compatible

@python_2_unicode_compatible
class Continent(models.Model):
    """Continent."""

    name = models.CharField(max_length=255)
    info = models.TextField(null=True, blank=True)
    latitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )
    longitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name

    @property
    def location_field_indexing(self):
        """Location for indexing.

        Used in Elasticsearch indexing/tests of `geo_distance` native filter.
        """
        return {
            'lat': self.latitude,
            'lon': self.longitude,
        }

books/models/country.py

@python_2_unicode_compatible
class Country(models.Model):
    """Country."""

    name = models.CharField(max_length=255)
    info = models.TextField(null=True, blank=True)
    continent = models.ForeignKey(
        'books.Continent',
        on_delete=models.CASCADE
    )
    latitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )
    longitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name

    @property
    def location_field_indexing(self):
        """Location for indexing.

        Used in Elasticsearch indexing/tests of `geo_distance` native
        filter.
        """
        return {
            'lat': self.latitude,
            'lon': self.longitude,
        }

books/models/city.py

@python_2_unicode_compatible
class City(models.Model):
    """City."""

    name = models.CharField(max_length=255)
    info = models.TextField(null=True, blank=True)
    country = models.ForeignKey('books.Country', on_delete=models.CASCADE)
    latitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )
    longitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return self.name

    @property
    def location_field_indexing(self):
        """Location for indexing.

        Used in Elasticsearch indexing/tests of `geo_distance` native
        filter.
        """
        return {
            'lat': self.latitude,
            'lon': self.longitude,
        }

books/models/address.py

from django.db import models
from django_elasticsearch_dsl_drf.wrappers import dict_to_obj

from six import python_2_unicode_compatible

@python_2_unicode_compatible
class Address(models.Model):
    """Address."""

    street = models.CharField(max_length=255)
    house_number = models.CharField(max_length=60)
    appendix = models.CharField(max_length=30, null=True, blank=True)
    zip_code = models.CharField(max_length=60)
    city = models.ForeignKey('books.City', on_delete=models.CASCADE)
    latitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )
    longitude = models.DecimalField(
        null=True,
        blank=True,
        decimal_places=15,
        max_digits=19,
        default=0
    )

    class Meta(object):
        """Meta options."""

        ordering = ["id"]

    def __str__(self):
        return "{} {} {} {}".format(
            self.street,
            self.house_number,
            self.appendix,
            self.zip_code
        )

    @property
    def location_field_indexing(self):
        """Location for indexing.

        Used in Elasticsearch indexing/tests of `geo_distance` native
        filter.
        """
        return {
            'lat': self.latitude,
            'lon': self.longitude,
        }

    @property
    def country_indexing(self):
        """Country data (nested) for indexing.

        Example:

        >>> mapping = {
        >>>     'country': {
        >>>         'name': 'Netherlands',
        >>>         'city': {
        >>>             'name': 'Amsterdam',
        >>>         }
        >>>     }
        >>> }

        :return:
        """
        wrapper = dict_to_obj({
            'name': self.city.country.name,
            'city': {
                'name': self.city.name
            }
        })

        return wrapper

    @property
    def continent_indexing(self):
        """Continent data (nested) for indexing.

        Example:

        >>> mapping = {
        >>>     'continent': {
        >>>         'name': 'Asia',
        >>>         'country': {
        >>>             'name': 'Netherlands',
        >>>             'city': {
        >>>                 'name': 'Amsterdam',
        >>>             }
        >>>         }
        >>>     }
        >>> }

        :return:
        """
        wrapper = dict_to_obj({
            'name': self.city.country.continent.name,
            'country': {
                'name': self.city.country.name,
                'city': {
                    'name': self.city.name,
                }
            }
        })

        return wrapper
Sample document
Index definition

To separate dev/test/staging/production indexes, the following approach is recommended.

Settings

settings/base.py

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.address': 'address',
}

settings/testing.py

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.address': 'test_address',
}

settings/production.py

# Name of the Elasticsearch index
ELASTICSEARCH_INDEX_NAMES = {
    'search_indexes.documents.address': 'prod_address',
}
Document index

search_indexes/documents/address.py

from django.conf import settings

from django_elasticsearch_dsl import Document, Index, fields
from django_elasticsearch_dsl_drf.compat import KeywordField, StringField

from books.models import Address

from .analyzers import html_strip


INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

# See Elasticsearch Indices API reference for available settings
INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1
)

@INDEX.doc_type
class AddressDocument(Document):
    """Address Elasticsearch document."""

    # In different parts of the code different fields are used. There are
    # a couple of use cases: (1) more-like-this functionality, where `title`,
    # `description` and `summary` fields are used, (2) search and filtering
    # functionality where all of the fields are used.

    # ID
    id = fields.IntegerField(attr='id')

    # ********************************************************************
    # *********************** Main data fields for search ****************
    # ********************************************************************

    street = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
        }
    )

    house_number = StringField(analyzer=html_strip)

    appendix = StringField(analyzer=html_strip)

    zip_code = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
        }
    )

    # ********************************************************************
    # ********** Additional fields for search and filtering **************
    # ********************************************************************

    # City object
    city = fields.ObjectField(
        properties={
            'name': StringField(
                analyzer=html_strip,
                fields={
                    'raw': KeywordField(),
                    'suggest': fields.CompletionField(),
                }
            ),
            'info': StringField(analyzer=html_strip),
            'location': fields.GeoPointField(attr='location_field_indexing'),
            'country': fields.ObjectField(
                properties={
                    'name': StringField(
                        analyzer=html_strip,
                        fields={
                            'raw': KeywordField(),
                            'suggest': fields.CompletionField(),
                        }
                    ),
                    'info': StringField(analyzer=html_strip),
                    'location': fields.GeoPointField(
                        attr='location_field_indexing'
                    )
                }
            )
        }
    )

    # Country object
    country = fields.NestedField(
        attr='country_indexing',
        properties={
            'name': StringField(
                analyzer=html_strip,
                fields={
                    'raw': KeywordField(),
                    'suggest': fields.CompletionField(),
                }
            ),
            'city': fields.ObjectField(
                properties={
                    'name': StringField(
                        analyzer=html_strip,
                        fields={
                            'raw': KeywordField(),
                        },
                    ),
                },
            ),
        },
    )

    # Continent object
    continent = fields.NestedField(
        attr='continent_indexing',
        properties={
            'name': StringField(
                analyzer=html_strip,
                fields={
                    'raw': KeywordField(),
                    'suggest': fields.CompletionField(),
                }
            ),
            'country': fields.NestedField(
                properties={
                    'name': StringField(
                        analyzer=html_strip,
                        fields={
                            'raw': KeywordField(),
                        }
                    ),
                    'city': fields.NestedField(
                        properties={
                            'name': StringField(
                                analyzer=html_strip,
                                fields={
                                    'raw': KeywordField(),
                                }
                            )
                        }
                    )
                }
            )
        }
    )

    location = fields.GeoPointField(attr='location_field_indexing')

    class Meta(object):
        """Meta options."""

        model = Address  # The model associate with this Document
Sample serializer

search_indexes/serializers/address.py

from django_elasticsearch_dsl_drf.serializers import DocumentSerializer

from ..documents import AddressDocument


class AddressDocumentSerializer(DocumentSerializer):
    """Serializer for address document."""

    class Meta(object):
        """Meta options."""

        document = AddressDocument
        fields = (
            'id',
            'street',
            'house_number',
            'appendix',
            'zip_code',
            'city',
            'country',
            'continent',
            'location',
        )
Sample view

search_indexes/viewsets/address.py

from django_elasticsearch_dsl_drf.constants import (
    LOOKUP_FILTER_GEO_DISTANCE,
    LOOKUP_FILTER_GEO_POLYGON,
    LOOKUP_FILTER_GEO_BOUNDING_BOX,
    SUGGESTER_COMPLETION,
)
from django_elasticsearch_dsl_drf.filter_backends import (
    DefaultOrderingFilterBackend,
    FacetedSearchFilterBackend,
    FilteringFilterBackend,
    GeoSpatialFilteringFilterBackend,
    GeoSpatialOrderingFilterBackend,
    NestedFilteringFilterBackend,
    OrderingFilterBackend,
    SearchFilterBackend,
    SuggesterFilterBackend,
)
from django_elasticsearch_dsl_drf.pagination import LimitOffsetPagination
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

from ..documents import AddressDocument
from ..serializers import AddressDocumentSerializer

class AddressDocumentViewSet(DocumentViewSet):
    """The AddressDocument view."""

    document = AddressDocument
    serializer_class = AddressDocumentSerializer
    lookup_field = 'id'
    filter_backends = [
        FacetedSearchFilterBackend,
        FilteringFilterBackend,
        OrderingFilterBackend,
        SearchFilterBackend,
        GeoSpatialFilteringFilterBackend,
        GeoSpatialOrderingFilterBackend,
        NestedFilteringFilterBackend,
        DefaultOrderingFilterBackend,
        SuggesterFilterBackend,
    ]
    pagination_class = LimitOffsetPagination
    # Define search fields
    search_fields = (
        'street',
        'zip_code',
        'city.name',
        'city.country.name',
    )
    # Define filtering fields
    filter_fields = {
        'id': None,
        'city': 'city.name.raw',
    }
    # Nested filtering fields
    nested_filter_fields = {
        'continent_country': {
            'field': 'continent.country.name.raw',
            'path': 'continent.country',
        },
        'continent_country_city': {
            'field': 'continent.country.city.name.raw',
            'path': 'continent.country.city',
        },
    }
    # Define geo-spatial filtering fields
    geo_spatial_filter_fields = {
        'location': {
            'lookups': [
                LOOKUP_FILTER_GEO_BOUNDING_BOX,
                LOOKUP_FILTER_GEO_DISTANCE,
                LOOKUP_FILTER_GEO_POLYGON,

            ],
        },
    }
    # Define ordering fields
    ordering_fields = {
        'id': None,
        'street': None,
        'city': 'city.name.raw',
        'country': 'city.country.name.raw',
        'zip_code': None,
    }
    # Define ordering fields
    geo_spatial_ordering_fields = {
        'location': None,
    }
    # Specify default ordering
    ordering = (
        'id',
        'street.raw',
        'city.name.raw',
    )
    # Suggester fields
    suggester_fields = {
        'street_suggest': {
            'field': 'street.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        },
        'city_suggest': {
            'field': 'city.name.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        },
        'country_suggest': {
            'field': 'city.country.name.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        }
    }

    # Facets
    faceted_search_fields = {
        'city': {
            'field': 'city.name.raw',
            'enabled': True,
        },
        'country': {
            'field': 'city.country.name.raw',
            'enabled': True,
        },
    }
Usage example

Considering samples above, you should be able to perform the search, sorting and filtering actions described below.

Sample queries
Nested filtering

Filter documents by nested field

Filter documents by field (continent.country) “Armenia”.

http://127.0.0.1:8000/search/addresses/?continent_country=Armenia

Filter documents by field (continent.country.city) “Amsterdam”.

http://127.0.0.1:8000/search/addresses/?continent_country_city=Amsterdam
Filtering

Filter documents by field

Filter documents by field (city) “Dublin”.

http://127.0.0.1:8000/search/addresses/?city=Dublin

Filter documents by multiple fields

Filter documents by field (states) “published” and “in_progress”.

http://127.0.0.1:8000/search/addresses/?city__in=Yerevan__Dublin
Ordering

The - prefix means ordering should be descending.

Order documents by field (descending)

Order documents by field country (ascending).

http://127.0.0.1:8000/search/addresses/?ordering=-country
Suggestions

The suggest feature suggests similar looking terms based on a provided text by using a suggester.

Note

The SuggesterFilterBackend filter backend can be used in the suggest custom view action/route only. Usages outside of the are suggest action/route are restricted.

There are three options available here: term, phrase and completion.

Note

Suggestion functionality is exclusive. Once you have queried the SuggesterFilterBackend, the latter will transform your current search query into suggestion search query (which is very different). Therefore, always add it as the very last filter backend.

Suggest completion for field country.

http://127.0.0.1:8000/search/addresses/suggest/?country_suggest__completion=Ar

Suggest completion for field city.

http://127.0.0.1:8000/search/addresses/suggest/?city_suggest__completion=Ye
Nested aggregations/facets

At the moment, nested aggregations/facets are not supported out of the box. Out of the box support will surely land in the package one day, but for now, there’s a simple and convenient way of implementing nested aggregations/facets with minimal efforts. Consider the following example.

search_indexes/backends/nested_continents.py

from django_elasticsearch_dsl_drf.filter_backends.mixins import (
    FilterBackendMixin,
)
from rest_framework.filters import BaseFilterBackend

class NestedContinentsBackend(BaseFilterBackend, FilterBackendMixin):
    """Adds nesting to continents."""

    faceted_search_param = 'nested_facet'

    def get_faceted_search_query_params(self, request):
        """Get faceted search query params.

        :param request: Django REST framework request.
        :type request: rest_framework.request.Request
        :return: List of search query params.
        :rtype: list
        """
        query_params = request.query_params.copy()
        return query_params.getlist(self.faceted_search_param, [])

    def filter_queryset(self, request, queryset, view):
        """Filter the queryset.
        :param request: Django REST framework request.
        :param queryset: Base queryset.
        :param view: View.
        :type request: rest_framework.request.Request
        :type queryset: elasticsearch_dsl.search.Search
        :type view: rest_framework.viewsets.ReadOnlyModelViewSet
        :return: Updated queryset.
        :rtype: elasticsearch_dsl.search.Search
        """
        facets = self.get_faceted_search_query_params(request)

        if 'continent' in facets:
            queryset \
                .aggs\
                .bucket('continents',
                        'nested',
                        path='continent') \
                .bucket('continent_name',
                        'terms',
                        field='continent.name.raw',
                        size=10) \
                .bucket('counties',
                        'nested',
                        path='continent.country') \
                .bucket('country_name',
                        'terms',
                        field='continent.country.name.raw',
                        size=10) \
                .bucket('city',
                        'nested',
                        path='continent.country.city') \
                .bucket('city_name',
                        'terms',
                        field='continent.country.city.name.raw',
                        size=10)

        return queryset

The view will look as follows:

search_indexes/viewsets/address.py

from django_elasticsearch_dsl_drf.constants import (
    LOOKUP_FILTER_GEO_DISTANCE,
    LOOKUP_FILTER_GEO_POLYGON,
    LOOKUP_FILTER_GEO_BOUNDING_BOX,
    SUGGESTER_COMPLETION,
)
from django_elasticsearch_dsl_drf.filter_backends import (
    DefaultOrderingFilterBackend,
    FacetedSearchFilterBackend,
    FilteringFilterBackend,
    GeoSpatialFilteringFilterBackend,
    GeoSpatialOrderingFilterBackend,
    NestedFilteringFilterBackend,
    OrderingFilterBackend,
    SearchFilterBackend,
    SuggesterFilterBackend,
)
from django_elasticsearch_dsl_drf.pagination import LimitOffsetPagination
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

from ..backends import NestedContinentsBackend
from ..documents import AddressDocument
from ..serializers import AddressDocumentSerializer

class AddressDocumentViewSet(DocumentViewSet):
    """The AddressDocument view."""

    document = AddressDocument
    serializer_class = AddressDocumentSerializer
    lookup_field = 'id'
    filter_backends = [
        FacetedSearchFilterBackend,
        FilteringFilterBackend,
        OrderingFilterBackend,
        SearchFilterBackend,
        GeoSpatialFilteringFilterBackend,
        GeoSpatialOrderingFilterBackend,
        NestedContinentsBackend,
        NestedFilteringFilterBackend,
        DefaultOrderingFilterBackend,
        SuggesterFilterBackend,
    ]
    pagination_class = LimitOffsetPagination
    # Define search fields
    search_fields = (
        'street',
        'zip_code',
        'city.name',
        'city.country.name',
    )
    # Define filtering fields
    filter_fields = {
        'id': None,
        'city': 'city.name.raw',
    }
    # Nested filtering fields
    nested_filter_fields = {
        'continent_country': {
            'field': 'continent.country.name.raw',
            'path': 'continent.country',
        },
        'continent_country_city': {
            'field': 'continent.country.city.name.raw',
            'path': 'continent.country.city',
        },
    }
    # Define geo-spatial filtering fields
    geo_spatial_filter_fields = {
        'location': {
            'lookups': [
                LOOKUP_FILTER_GEO_BOUNDING_BOX,
                LOOKUP_FILTER_GEO_DISTANCE,
                LOOKUP_FILTER_GEO_POLYGON,

            ],
        },
    }
    # Define ordering fields
    ordering_fields = {
        'id': None,
        'street': None,
        'city': 'city.name.raw',
        'country': 'city.country.name.raw',
        'zip_code': None,
    }
    # Define ordering fields
    geo_spatial_ordering_fields = {
        'location': None,
    }
    # Specify default ordering
    ordering = (
        'id',
        'street.raw',
        'city.name.raw',
    )
    # Suggester fields
    suggester_fields = {
        'street_suggest': {
            'field': 'street.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        },
        'city_suggest': {
            'field': 'city.name.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        },
        'country_suggest': {
            'field': 'city.country.name.suggest',
            'suggesters': [
                SUGGESTER_COMPLETION,
            ],
        }
    }

    # Facets
    faceted_search_fields = {
        'city': {
            'field': 'city.name.raw',
            'enabled': True,
        },
        'country': {
            'field': 'city.country.name.raw',
            'enabled': True,
        },
    }

More like this

More like this functionality.

Usage example

Sample document
from django.conf import settings

from django_elasticsearch_dsl import Document, Index, fields
from django_elasticsearch_dsl_drf.compat import KeywordField, StringField
from django_elasticsearch_dsl_drf.analyzers import edge_ngram_completion

from books.models import Book

from .analyzers import html_strip

INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__])

# See Elasticsearch Indices API reference for available settings
INDEX.settings(
    number_of_shards=1,
    number_of_replicas=1,
    blocks={'read_only_allow_delete': False}
)


@INDEX.doc_type
class BookDocument(Document):

    # ID
    id = fields.IntegerField(attr='id')

    title = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'suggest': fields.CompletionField(),
            'edge_ngram_completion': StringField(
                analyzer=edge_ngram_completion
            ),
            'mlt': StringField(analyzer='english'),
        }
    )

    description = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'mlt': StringField(analyzer='english'),
        }
    )

    summary = StringField(
        analyzer=html_strip,
        fields={
            'raw': KeywordField(),
            'mlt': StringField(analyzer='english'),
        }
    )

    # ...

    class Meta(object):
        """Meta options."""

        model = Book  # The model associate with this Document

    def prepare_summary(self, instance):
        """Prepare summary."""
        return instance.summary[:32766]
Sample view
from django_elasticsearch_dsl_drf.filter_backends import (
    FilteringFilterBackend,
    IdsFilterBackend,
    OrderingFilterBackend,
    PostFilterFilteringFilterBackend,
    SearchFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import (
    DocumentViewSet,
    MoreLikeThisMixin,
)

from .serializers import BookDocumentSerializer

class BookMoreLikeThisDocumentViewSet(DocumentViewSet,
                                      MoreLikeThisMixin):
    """Same as BookDocumentViewSet, with more-like-this and no facets."""

    # ...

    document = BookDocument
    lookup_field = 'id'
    serializer_class = BookDocumentSerializer

    # ...

    filter_backends = [
        # ...
        FilteringFilterBackend,
        PostFilterFilteringFilterBackend,
        IdsFilterBackend,
        OrderingFilterBackend,
        SearchFilterBackend,
        # ...
    ]

    # More-like-this options
    more_like_this_options = {
        'fields': (
            'title.mlt',
            'summary.mlt',
            'description.mlt',
        )
    }
Sample request
http://localhost:8000/search/books-more-like-this-no-options/1007587/more_like_this/
Generated query
{
  "query": {
    "more_like_this": {
      "fields": [
        "title.mlt",
        "summary.mlt",
        "description.mlt"
      ],
      "like": {
        "_index": "book",
        "_id": "1007587",
        "_type": "book_document"
      }
    }
  },
  "from": 0,
  "size": 14,
  "sort": [
    "_score"
  ]
}
Options

Pretty much all Elasticsearch more-like-this options available. You might be particularly interested in the following:

  • min_term_freq
  • max_query_terms
  • unlike
  • stop_words

Global aggregations

Global aggregations (facets) are regular aggregations, which are not influenced by the search query/filter. They deliver results similar to post_filter.

Sample view

from django_elasticsearch_dsl_drf.filter_backends import (
    CompoundSearchFilterBackend,
    DefaultOrderingFilterBackend,
    FacetedSearchFilterBackend,
    OrderingFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet

from .documents import BookDocument
from .serializers import BookDocumentSerializer

class BookCompoundSearchBackendDocumentViewSet(DocumentViewSet):

    document = BookDocument
    serializer_class = BookDocumentSerializer
    lookup_field = 'id'

    filter_backends = [
        # ...
        OrderingFilterBackend,
        DefaultOrderingFilterBackend,
        CompoundSearchFilterBackend,
        FacetedSearchFilterBackend,
        # ...
    ]

    faceted_search_fields = {
        'state_global': {
            'field': 'state.raw',
            'enabled': True,
            'global': True,  # This makes the aggregation global
        },
    }

Sample request

http://localhost:8000/search/books/?facet=state_global&state=rejected

Generated query

{
   "from":0,
   "query":{
      "bool":{
         "filter":[
            {
               "terms":{
                  "state.raw":[
                     "rejected"
                  ]
               }
            }
         ]
      }
   },
   "size":25,
   "aggs":{
      "_filter_state_global":{
         "aggs":{
            "state_global":{
               "terms":{
                  "field":"state.raw"
               }
            }
         },
         "global":{

         }
      }
   },
   "sort":[
      "id",
      "title",
      "price"
   ]
}

Sample response

{
    "count": 25,
    "next": null,
    "previous": null,
    "facets": {
        "_filter_state_global": {
            "state_global": {
                "buckets": [
                    {
                        "doc_count": 29,
                        "key": "not_published"
                    },
                    {
                        "doc_count": 25,
                        "key": "in_progress"
                    },
                    {
                        "doc_count": 25,
                        "key": "rejected"
                    },
                    {
                        "doc_count": 21,
                        "key": "cancelled"
                    },
                    {
                        "doc_count": 17,
                        "key": "published"
                    }
                ],
                "sum_other_doc_count": 0,
                "doc_count_error_upper_bound": 0
            },
            "doc_count": 117
        }
    },
    "results": [
        {
            "id": 1007489,
            "title": "Cupiditate qui nulla itaque maxime impedit.",
            "description": null,
            "summary": "Aut recusandae architecto incidunt quaerat odio .",
            "authors": [
                "Evy Vermeulen",
                "Tycho Weijland",
                "Rik Zeldenrust"
            ],
            "publisher": "Overdijk Inc",
            "publication_date": "2014-02-28",
            "state": "rejected",
            "isbn": "978-0-15-184366-4",
            "price": 6.53,
            "pages": 82,
            "stock_count": 30,
            "tags": [
                "Trilogy"
            ],
            "highlight": {},
            "null_field": null,
            "score": null
        },
        # ...
    ]
}

Configuration tweaks

Ignore certain Elasticsearch exceptions

class BookIgnoreIndexErrorsDocumentViewSet(DocumentViewSet):

    # ...
    ignore = [404]
    # ...

Source filtering backend

Allows to control how the _source field is returned with every hit.

By default operations return the contents of the _source field unless you have used the stored_fields parameter or if the _source field is disabled.

You can turn off _source retrieval by using the source parameter:

from django_elasticsearch_dsl_drf.filter_backends import (
    SourceBackend
)
from django_elasticsearch_dsl_drf.viewsets import (
    BaseDocumentViewSet,
)

# Local article document definition
from .documents import ArticleDocument

# Local article document serializer
from .serializers import ArticleDocumentSerializer

class ArticleDocumentView(BaseDocumentViewSet):

    document = ArticleDocument
    serializer_class = ArticleDocumentSerializer
    filter_backends = [SourceBackend,]
    source = ["title"]

To disable _source retrieval set to False:

# ...
source = False
# ...

The source also accepts one or more wildcard patterns to control what parts of the _source should be returned:

# ...
source = ["title", "author.*"]
# ...

Finally, for complete control, you can specify both includes and excludes patterns:

# ...
source = {
    "includes": ["title", "author.*"],
    "excludes": [ "*.description" ]
}
# ...

Note

Source can make queries lighter. However, it can break current functionality. Use it with caution.

Indexing troubleshooting

When indexing lots of data (millions of records), you might get timeout exceptions.

A couple of possible solutions (complementary) are listed below. All of them are independent and not strictly related to each other. Thus, you may just use one or a couple or all of them. It’s totally up to you.

If you want to test what works best for you, use this test dataset (Postgres) containing 1.8 million location records for search_indexes.documents.location.LocationDocument document.

Timeout

For re-indexing, you might want to increase the timeout to avoid time-out exceptions.

To do that, make a new settings file (indexing) and add the following:

settings/indexing.py

from .base import *  # Import from your main/production settings.

# Override the elasticsearch configuration and provide a custom timeout
ELASTICSEARCH_DSL = {
    'default': {
        'hosts': 'localhost:9200',
        'timeout': 60,  # Custom timeout
    },
}

Then rebuild your search index specifying the indexing settings:

./manage.py search_index --rebuild -f --settings=settings.indexing

Note, that you may as well specify the timeout in your global settings. However, if you’re happy with how things work in production (except for the indexing part), you may do as suggested (separate indexing settings).

Chunk size

Note, that this feature is (yet) only available in the forked version barseghyanartur/django-elasticsearch-dsl.

Install it as follows:

pip install https://github.com/barseghyanartur/django-elasticsearch-dsl/archive/mjl-index-speedup-2-additions.zip

Specify the chunk_size param as follows (we set chunk_size to 50 in this case):

./manage.py search_index --rebuild -f --chunk-size=50

Use parallel indexing

Parallel indexing speeds things up (drastically). In my tests I got a speedup boost of 66 percent on 1.8 million records.

Note, that this feature is (yet) only available in the forked versions barseghyanartur/django-elasticsearch-dsl. or mjl/django-elasticsearch-dsl.

Install it as follows:

barseghyanartur/django-elasticsearch-dsl fork

pip install https://github.com/barseghyanartur/django-elasticsearch-dsl/archive/mjl-index-speedup-2-additions.zip

mjl/django-elasticsearch-dsl fork

pip install https://github.com/mjl/django-elasticsearch-dsl/archive/mjl-index-speedup.zip

In order to make use of it, define set parallel_indexing to True on the document meta.

yourapp/documents.py

class LocationDocument(Document):

    # ...

    class Meta(object):
        """Meta options."""

        model = Location
        parallel_indexing = True

Limit the number of items indexed at once

This is very close to the chunk_size shown above, but might work better on heavy querysets. Instead of processing entire queryset at once, it’s sliced instead. So, if you have 2 million records in your queryset and you wish to index them by chunks of 20 thousands at once, specify the queryset_pagination on the document meta:

yourapp/documents.py

class LocationDocument(Document):

    # ...

    class Meta(object):
        """Meta options."""

        model = Location
        queryset_pagination = 50

You may even make it dynamic based on the settings loaded. So, for instance, you may have it set to None in production (if you were happy with how things were) and provide a certain value for it in the dedicated indexing settings (as already has been mentioned above).

settings/base.py

# Main/production settings
ELASTICSEARCH_DSL_QUERYSET_PAGINATION = None

settings/indexing.py

# Indexing only settings
ELASTICSEARCH_DSL_QUERYSET_PAGINATION = 1000

yourapp/documents.py

from django.conf import settings

# ...

class LocationDocument(Document):

    # ...

    class Meta(object):
        """Meta options."""

        model = Location
        queryset_pagination = settings.ELASTICSEARCH_DSL_QUERYSET_PAGINATION

FAQ

You will find a lot of useful information in the documentation.

Additionally, all raised issues that were questions have been marked as question, so you could take a look at the closed (question) issues.

Questions and answers

Question

  • Is it possible to search sub string in word?
  • How to implement partial/fuzzy search?

Answer

Yes. There are many ways doing this in Elasticsearch.

To mention a couple:


Question

Can we use Django REST Framework serializers.ModelSerializer directly?

Answer

No, but you could use serializers.Serializer. Read the docs.


Question

How can I order search results overall relevance

Answer

That’s _score. See the following example.

ordering = ('_score', 'id', 'title', 'price',)

In the given example, results are sorted by the score (which is relevance), then by id, title and price.


Question

How can I separate my development/production/acceptance/test indexes?

Answer

It’s documented here.


Question

How can I sync my database with Elasticsearch indexes.

Answer

It’s documented here.


Question

I keep getting [FORBIDDEN/12/index read-only / allow delete (api)] error when saving models despite having blocks={'read_only_allow_delete': None}, in settings.

Answer

Once of the possible reasons for the mentioned symptom might be low disk space.

frontend demo for django-elasticsearch-dsl-drf

Frontend demo for django-elasticsearch-dsl-drf

Based on Book model, BookDocument and BookFrontendDocumentViewSet viewset.

Quick start

From the project root directory.

Install the django requirements

Since project supports Django versions from 1.8 to 2.1, you may install any version you want.

To install latest LTS version, do:

pip install -r examples/requirements/django_1_11.txt
Install Elasticsearch requirements

Since project supports Elasticsearch versions from 2.x to 6.x, you may install any version you want.

To install requirements for 6.x, do:

pip install -r examples/requirements/elastic_6x.txt
Run Elasticsearch

It’s really easy using Docker.

To run 6.3.2 using Docker, do:

docker pull docker.elastic.co/elasticsearch/elasticsearch:6.3.2
docker run -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" docker.elastic.co/elasticsearch/elasticsearch:6.3.2
Build Elasticsearch index

First, create some test data:

./scripts/create_test_data.sh

Then build Elasticsearch index:

./scripts/rebuild_index.sh
Install React requirements

Note, that you should be using NodeJS > 7.5.

Typically, you would first do:

nvm use 9

Then run the installer:

./scripts/yarn_install.sh
Run Django

The following script would run the Django server which is used by the demo app.

./scripts/runserver.sh
Run React demo app

Finally, run the React demo app:

./scripts/frontend.sh

Open http://localhost:3000 to view the frontend in the browser.

Release history and notes

Sequence based identifiers are used for versioning (schema follows below):

major.minor[.revision]
  • It’s always safe to upgrade within the same minor version (for example, from 0.3 to 0.3.4).
  • Minor version changes might be backwards incompatible. Read the release notes carefully before upgrading (for example, when upgrading from 0.3.4 to 0.4).
  • All backwards incompatible changes are mentioned in this document.

0.20.2

2019-08-30

  • Minor improvements in test coverage.

0.20.1

2019-08-18

  • Minor Elasticsearch 7.x compatibility fixes.

0.20

2019-08-17

  • Adding Elasticsearch 7.x support.

0.19

2019-08-06

Note

Dropping support for Elasticsearch versions prior 6.x. This is unfortunate, but this project depends on the upstream django-elasticsearch-dsl where as of version 6.4.x the support for older Elasticsearch versions was dropped. Use django-elasticsearch-dsl-drf version 0.18 if you need to work with 5.x or 2.x.

  • Dropping support for Elasticsearch versions prior to 6.x.

0.18

2019-06-26

Note

Support for Django versions prior 1.11 has been dropped. Support for Django REST Framework prior 3.9 has been dropped.

  • Dropping support for Django versions prior 1.11.
  • Dropping support for Django REST Framework versions prior 3.9.
  • Fix Django REST Framework deprecations.

0.17.7

2019-05-30

Note

Support for Django 1.8, 1.9 and 1.10 will be dropped in the next release. As usual, compatibility shims won’t be removed directly. The change will affect the test matrix only first.

  • Prevent unicode errors in tests on Python 2.7.
  • Fixes in occasionally failing search test (test_search and test_filtering_geo_spatial).
  • Working travis.
  • Fixed issue with errors on empty ids filter.

0.17.6

2019-04-08

  • Minor fixes.
  • Additions to the docs.

0.17.5

2019-04-03

Note

Dropping support for Python 3.4. As of this version everything works, but no longer tested.

  • Minor fixes.
  • Dropping Python 3.4 support.
  • Django 2.2 support.

0.17.4

2019-03-13

  • Source backend.

0.17.3

2019-02-08

  • Obey object permissions.

0.17.2

2019-01-07

  • Add nested ordering.

0.17.1

2018-12-12

  • Skipping the new context suggester tests for Elasticsearch 2.x and a number of other 2.x related fixes in tests.
  • A number of 5.x fixes in tests.

0.17

2018-12-12

Note

Release supported by whythawk.

  • Added support for context suggesters (category and geo). Note, that this functionality is available for Elasticsearch 5.x and 6.x (thus, not for Elasticsearch 2.x).
  • Added support for size attribute on suggesters.

0.16.3

2018-10-31

Note

Release dedicated to Charles Aznavour.

  • Make it possible to ignore certain Elastic exceptions by providing the appropriate ignore argument (on the view level). Default behaviour is intact. Set it to a list of integers (error codes) if you need it so.

0.16.2

2018-09-21

  • Tested yet untested pip_helpers module.
  • More tests.

0.16.1

2018-09-18

  • Make it possible to control the size of the functional suggester queries.

0.16

2018-09-10

Note

This release contains minor backwards incompatible changes. You might need to update your code if you have been making use of nested search.

Old way of declaring nested search fields

search_nested_fields = {
    'country': ['name'],
    'country.city': ['name'],
}

New way of declaring nested search fields

search_nested_fields = {
    'country': {
        'path': 'country',
        'fields': ['name'],
    },
    'city': {
        'path': 'country.city',
        'fields': ['name'],
    },
}
  • Changes in nested search. This affects usage of both historical SearchFilterBackend and CompoundSearchFilterBackend. Update your code accordingly.
  • Take meta property using of the document Meta into consideration.

0.15.1

2018-08-22

  • More tests.
  • Fixes in docs.

0.15

2018-08-10

  • Global aggregations.

0.14

2018-08-06

  • More like this support through detail action.

0.13.2

2018-08-03

  • Successfully tested against Python 3.7 and Django 2.1.
  • Unified the base BaseSearchFilterBackend class.
  • Minor clean up and fixes in docs.
  • Upgrading test suite to modern versions (pytest, tox, factory_boy, Faker). Removing unused dependencies from requirements (drf-extensions).
  • Fixed missing PDF generation in offline documentation (non ReadTheDocs). The rst2pdf package (which does not support Python 3) has been replaced with rinohtype package (which does support Python 3).

0.13.1

2018-07-26

  • Minor fix in suggesters on Elasticsearch 6.x.

0.13

2018-07-23

Note

Release dedicated to Guido van Rossum, the former Python BDFL, who resigned from his BDFL position recently. Guido knew it better than we all do. His charisma, talent and leadership will be certainly missed a lot by the community. Thumbs up again for the best BDFL ever.

  • The SimpleQueryStringSearchFilterBackend backend has been implemented.
  • Minor fixes in the MultiMatchSearchFilterBackend backend.

0.12

2018-07-21

  • New-style Search Filter Backends. Old style SearchFilterBackend is still supported (until at least version 0.16), but is deprecated. Migrate to CompoundSearchFilterBackend. MultiMatchSearchFilterBackend introduced (the name speaks for itself).
  • From now on, your views would also work with model- and object-level permissions of the Django REST Framework (such as DjangoModelPermissions, DjangoModelPermissionsOrAnonReadOnly and DjangoObjectPermissions). Correspondent model or object would be used for that. If you find it incorrect in your case, write custom permissions and declare the explicitly in your view-sets.
  • Fixed geo-spatial geo_distance ordering for Elastic 5.x. and 6.x.
  • Fixes occasionally failing tests.

0.11

2018-07-15

Note

This release contains backwards incompatible changes. You should update your Django code and front-end parts of your applications that were relying on the complex queries using | and : chars in the GET params.

Note

If you have used custom filter backends using SEPARATOR_LOOKUP_VALUE, SEPARATOR_LOOKUP_COMPLEX_VALUE or SEPARATOR_LOOKUP_COMPLEX_MULTIPLE_VALUE constants or split_lookup_complex_value helper method of the FilterBackendMixin, you most likely want to run your functional tests to see if everything still works.

Note

Do not keep things as they were in your own fork, since new search backends will use the | and : symbols differently.

Examples of old API requests vs new API requests

Note

Note, that | and : chars were mostly replaced with __ and ,.

Old API requests

http://127.0.0.1:8080/search/publisher/?search=name|reilly&search=city|london
http://127.0.0.1:8000/search/publishers/?location__geo_distance=100000km|12.04|-63.93
http://localhost:8000/api/articles/?id__terms=1|2|3
http://localhost:8000/api/users/?age__range=16|67|2.0
http://localhost:8000/api/articles/?id__in=1|2|3
http://localhost:8000/api/articles/?location__geo_polygon=40,-70|30,-80|20,-90|_name:myname|validation_method:IGNORE_MALFORMED

New API requests

http://127.0.0.1:8080/search/publisher/?search=name:reilly&search=city:london
http://127.0.0.1:8000/search/publishers/?location__geo_distance=100000km__12.04__-63.93
http://localhost:8000/api/articles/?id__terms=1__2__3
http://localhost:8000/api/users/?age__range=16__67__2.0
http://localhost:8000/api/articles/?id__in=1__2__3
http://localhost:8000/api/articles/?location__geo_polygon=40,-70__30,-80__20,-90___name,myname__validation_method,IGNORE_MALFORMED
  • SEPARATOR_LOOKUP_VALUE has been removed. Use SEPARATOR_LOOKUP_COMPLEX_VALUE and SEPARATOR_LOOKUP_COMPLEX_MULTIPLE_VALUE instead.
  • SEPARATOR_LOOKUP_NAME has been added.
  • The method split_lookup_complex_value has been removed. Use split_lookup_complex_value instead.
  • Default filter lookup option is added. In past, if no specific lookup was provided and there were multiple values for a single field to filter on, by default terms filter was used. The term lookup was used by default in similar situation for a single value to filter on. It’s now possible to declare default lookup which will be used when no lookup is given.
  • Removed deprecated views module. Import from viewsets instead.
  • Removed undocumented get_count helper from helpers module.

0.10

2018-07-06

  • Elasticsearch 6.x support.
  • Minor fixes.

0.9

2018-07-04

  • Introduced post_filter support.
  • Generalised the FilteringFilterBackend backend. Both PostFilterFilteringFilterBackend and NestedFilteringFilterBackend backends are now primarily based on it.
  • Reduced Elastic queries from 3 to 2 when using LimitOffsetPagination.

0.8.4

2018-06-27

Note

Release supported by Goldmund, Wyldebeast & Wunderliebe.

  • Added NestedFilteringFilterBackend backend.
  • Documentation updated with examples of implementing a nested aggregations/facets.

0.8.3

2018-06-25

  • It’s possible to retrieve original dictionary from DictionaryProxy object.
  • Added helper wrappers and helper functions as a temporary fix for issues in the django-elasticsearch-dsl.

0.8.2

2018-06-05

  • Minor fixes.

0.8.1

2018-06-05

  • Fixed wrong filter name in functional suggesters results into an error on Django 1.10 (and prior).
  • Documentation improvements.

0.8

2018-06-01

Note

Release supported by Goldmund, Wyldebeast & Wunderliebe.

Note

This release contain minor backwards incompatible changes. You should update your code.

    1. BaseDocumentViewSet (which from now on does not contain suggest functionality) has been renamed to DocumentViewSet (which does contain suggest functionality).
    1. You should no longer import from django_elasticsearch_dsl_drf.views. Instead, import from django_elasticsearch_dsl_drf.viewsets.
  • Deprecated django_elasticsearch_dsl_drf.views in favour of django_elasticsearch_dsl_drf.viewsets.
  • Suggest action/method has been moved to SuggestMixin class.
  • FunctionalSuggestMixin class introduced which resembled functionality of the SuggestMixin with several improvements/additions, such as advanced filtering and context-aware suggestions.
  • You can now define a default suggester in suggester_fields which will be used if you do not provide suffix for the filter name.

0.7.2

2018-05-09

Note

Release dedicated to the Victory Day, the victims of the Second World War and Liberation of Shushi.

  • Django REST framework 3.8.x support.

0.7.1

2018-04-04

Note

Release supported by Goldmund, Wyldebeast & Wunderliebe.

  • Add query boost support for search fields.

0.7

2018-03-08

Note

Dear ladies, congratulations on International Women’s Day

  • CoreAPI/CoreSchema support.

0.6.4

2018-03-05

  • Minor fix: explicitly use DocType in the ViewSets.

0.6.3

2018-01-03

  • Minor fix in the search backend.
  • Update the year in the license and code.

0.6.2

2017-12-29

  • Update example project (and the tests that are dependant on the example project) to work with Django 2.0.
  • Set minimal requirement for django-elasticsearch-dsl to 3.0.

0.6.1

2017-11-28

  • Documentation fixes.

0.6

2017-11-28

  • Added highlight backend.
  • Added nested search functionality.

0.5.1

2017-10-18

  • Fixed serialization of complex nested structures (lists of nested objects).
  • Documentation fixes.

0.5

2017-10-05

Note

This release contains changes that might be backwards incompatible for your project. If you have used dynamic document serializer django_elasticsearch_dsl_drf.serializers.DocumentSerializer with customisations (with use of serializers.SerializerMethodField, having the value parsed to JSON), just remove the custom parts.

  • Support for ObjectField, NestedField, GeoPointField, ListField, GeoShapeField (and in general, nesting fields either as a dictionary or list should not be a problem at all).
  • Dynamic serializer has been made less strict.
  • Added get_paginated_response_context methods to both PageNumberPagination and LimitOffsetPagination pagination classes to simplify customisations.

0.4.4

2017-10-02

  • Documentation improvements (Elasticsearch suggestions).
  • More tests (term and phrase suggestions).
  • Code style fixes.

0.4.3

2017-09-28

  • Documentation fixes.
  • Fixes in tests.
  • Improved factories.

0.4.2

2017-09-28

  • Added geo_bounding_box query support to the geo-spatial features.

0.4.1

2017-09-26

  • Fixes in docs.

0.4

2017-09-26

Note

This release contains changes that might be backwards incompatible for your project. Make sure to add the DefaultOrderingFilterBackend everywhere you have used the OrderingFilterBackend, right after the latter.

  • GeoSpatialFilteringFilterBackend filtering backend, supporting geo_distance and geo_polygon geo-spatial queries.
  • GeoSpatialOrderingFilterBackend ordering backend, supporting ordering of results for geo_distance filter.
  • OrderingFilterBackend no longer provides defaults when no ordering is given. In order to take care of the defaults include the DefaultOrderingFilterBackend in the list of filter_backends (after all other ordering backends).

0.3.12

2017-09-21

  • Added geo_distance filter. Note, that although functionally the filter would not change its’ behaviour, it is likely to be moved to a separate backend (geo_spatial). For now use as is.
  • Minor fixes.

0.3.11

2017-09-21

  • Added query argument to more_like_this helper.

0.3.10

2017-09-20

  • Minor fixes.
  • Simplified Elasticsearch version check.

0.3.9

2017-09-12

  • Python 2.x compatibility fix.

0.3.8

2017-09-12

  • Fixes tests on some environments.

0.3.7

2017-09-07

  • Docs fixes.

0.3.6

2017-09-07

  • Fixed suggestions test for Elasticsearch 5.x.
  • Added compat module for painless testing of Elastic 2.x to Elastic 5.x transition.

0.3.5

2017-08-24

  • Minor fixes in the ordering backend.
  • Improved tests and coverage.

0.3.4

2017-08-23

  • Minor fixes in the ordering backend.

0.3.3

2017-07-13

  • Minor fixes and improvements.

0.3.2

2017-07-12

  • Minor fixes and improvements.

0.3.1

2017-07-12

  • Minor Python2 fixes.
  • Minor documentation fixes.

0.3

2017-07-11

  • Add suggestions support (term, phrase and completion).

0.2.6

2017-07-11

  • Minor fixes.
  • Fixes in documentation.

0.2.5

2017-07-11

  • Fixes in documentation.

0.2.4

2017-07-11

  • Fixes in documentation.

0.2.3

2017-07-11

  • Fixes in documentation.

0.2.2

2017-07-11

  • Fixes in documentation.

0.2.1

2017-07-11

  • Fixes in documentation.

0.2

2017-07-11

  • Initial faceted search support.
  • Pagination support.

0.1.8

2017-06-26

  • Python2 fixes.
  • Documentation and example project improvements.

0.1.7

2017-06-25

  • Dynamic serializer for Documents.
  • Major improvements in documentation.

0.1.6

2017-06-23

  • Implemented gt, gte, lt and lte functional query lookups.
  • Implemented ids native filter lookup.

0.1.5

2017-06-22

  • Implemented endswith and contains functional filters.
  • Added tests for wildcard, exists, exclude and isnull filters. Improved range filter tests.
  • Improve more_like_this helper test.
  • Improve ordering tests.
  • Two additional arguments added to the more_like_this helper: min_doc_freq and max_doc_freq.
  • Minor documentation improvements.

0.1.4

2017-06-22

  • Added tests for in, term and terms filters.
  • Minor documentation fixes.

0.1.3

2017-06-21

  • Added tests for more_like_this helper, range and prefix filters.
  • Minor documentation improvements.

0.1.2

2017-06-20

  • Minor fixes in tests.

0.1.1

2017-06-20

  • Fixes in more_like_this helper.
  • Tiny documentation improvements.

0.1

2017-06-19

  • Initial beta release.

django_elasticsearch_dsl_drf package

Subpackages

django_elasticsearch_dsl_drf.fields package
Submodules
django_elasticsearch_dsl_drf.fields.common module

Common fields.

class django_elasticsearch_dsl_drf.fields.common.BooleanField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: rest_framework.fields.BooleanField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.common.CharField(**kwargs)[source]

Bases: rest_framework.fields.CharField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.common.DateField(format=<class 'rest_framework.fields.empty'>, input_formats=None, *args, **kwargs)[source]

Bases: rest_framework.fields.DateField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.common.FloatField(**kwargs)[source]

Bases: rest_framework.fields.FloatField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.common.IntegerField(**kwargs)[source]

Bases: rest_framework.fields.IntegerField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.common.IPAddressField(protocol='both', **kwargs)[source]

Bases: rest_framework.fields.IPAddressField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

django_elasticsearch_dsl_drf.fields.helpers module

Helpers.

django_elasticsearch_dsl_drf.fields.helpers.to_representation(value)[source]

To representation.

django_elasticsearch_dsl_drf.fields.nested_fields module

Nested fields.

class django_elasticsearch_dsl_drf.fields.nested_fields.GeoPointField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: django_elasticsearch_dsl_drf.fields.nested_fields.ObjectField

Geo point field.

class django_elasticsearch_dsl_drf.fields.nested_fields.GeoShapeField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: django_elasticsearch_dsl_drf.fields.nested_fields.ObjectField

Geo shape field.

class django_elasticsearch_dsl_drf.fields.nested_fields.NestedField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: django_elasticsearch_dsl_drf.fields.nested_fields.ObjectField

Nested field.

class django_elasticsearch_dsl_drf.fields.nested_fields.ObjectField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: rest_framework.fields.Field

Object field.

get_value(dictionary)[source]

Get value.

to_internal_value(data)[source]

To internal value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.nested_fields.ListField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: rest_framework.fields.Field

List field.

get_value(dictionary)[source]

Get value.

to_internal_value(data)[source]

To internal value.

to_representation(value)[source]

To representation.

Module contents

Fields.

class django_elasticsearch_dsl_drf.fields.BooleanField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: rest_framework.fields.BooleanField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.CharField(**kwargs)[source]

Bases: rest_framework.fields.CharField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.DateField(format=<class 'rest_framework.fields.empty'>, input_formats=None, *args, **kwargs)[source]

Bases: rest_framework.fields.DateField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.FloatField(**kwargs)[source]

Bases: rest_framework.fields.FloatField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.GeoPointField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: django_elasticsearch_dsl_drf.fields.nested_fields.ObjectField

Geo point field.

class django_elasticsearch_dsl_drf.fields.GeoShapeField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: django_elasticsearch_dsl_drf.fields.nested_fields.ObjectField

Geo shape field.

class django_elasticsearch_dsl_drf.fields.IntegerField(**kwargs)[source]

Bases: rest_framework.fields.IntegerField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.IPAddressField(protocol='both', **kwargs)[source]

Bases: rest_framework.fields.IPAddressField

Object field.

get_value(dictionary)[source]

Get value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.ListField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: rest_framework.fields.Field

List field.

get_value(dictionary)[source]

Get value.

to_internal_value(data)[source]

To internal value.

to_representation(value)[source]

To representation.

class django_elasticsearch_dsl_drf.fields.NestedField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: django_elasticsearch_dsl_drf.fields.nested_fields.ObjectField

Nested field.

class django_elasticsearch_dsl_drf.fields.ObjectField(read_only=False, write_only=False, required=None, default=<class 'rest_framework.fields.empty'>, initial=<class 'rest_framework.fields.empty'>, source=None, label=None, help_text=None, style=None, error_messages=None, validators=None, allow_null=False)[source]

Bases: rest_framework.fields.Field

Object field.

get_value(dictionary)[source]

Get value.

to_internal_value(data)[source]

To internal value.

to_representation(value)[source]

To representation.

django_elasticsearch_dsl_drf.filter_backends package
Subpackages
django_elasticsearch_dsl_drf.filter_backends.aggregations package
Submodules
django_elasticsearch_dsl_drf.filter_backends.aggregations.bucket_aggregations module
django_elasticsearch_dsl_drf.filter_backends.aggregations.metrics_aggregations module
django_elasticsearch_dsl_drf.filter_backends.aggregations.pipeline_aggregations module
Module contents
django_elasticsearch_dsl_drf.filter_backends.filtering package
Submodules
django_elasticsearch_dsl_drf.filter_backends.filtering.common module

Common filtering backend.

class django_elasticsearch_dsl_drf.filter_backends.filtering.common.FilteringFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Filtering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_PREFIX,
>>>     LOOKUP_FILTER_WILDCARD,
>>>     LOOKUP_QUERY_EXCLUDE,
>>>     LOOKUP_QUERY_ISNULL,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     FilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [FilteringFilterBackend,]
>>>     filter_fields = {
>>>         'title': 'title.raw',
>>>         'state': {
>>>             'field': 'state.raw',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_PREFIX,
>>>                 LOOKUP_FILTER_WILDCARD,
>>>                 LOOKUP_QUERY_EXCLUDE,
>>>                 LOOKUP_QUERY_ISNULL,
>>>             ],
>>>             'default_lookup': LOOKUP_FILTER_WILDCARD,
>>>         }
>>> }
classmethod apply_filter_prefix(queryset, options, value)[source]

Apply prefix filter.

Syntax:

/endpoint/?field_name__prefix={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_filter_range(queryset, options, value)[source]

Apply range filter.

Syntax:

/endpoint/?field_name__range={lower}__{upper}__{boost} /endpoint/?field_name__range={lower}__{upper}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_filter_term(queryset, options, value)[source]

Apply term filter.

Syntax:

/endpoint/?field_name={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_filter_terms(queryset, options, value)[source]

Apply terms filter.

Syntax:

/endpoint/?field_name__terms={value1}__{value2} /endpoint/?field_name__terms={value1}

Note, that number of values is not limited.

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (mixed: either str or iterable (list, tuple)) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_contains(queryset, options, value)[source]

Apply contains filter.

Syntax:

/endpoint/?field_name__contains={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_endswith(queryset, options, value)[source]

Apply endswith filter.

Syntax:

/endpoint/?field_name__endswith={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_exclude(queryset, options, value)[source]

Apply exclude functional query.

Syntax:

/endpoint/?field_name__isnull={value1}__{value2} /endpoint/?field_name__exclude={valu1}

Note, that number of values is not limited.

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_exists(queryset, options, value)[source]

Apply exists filter.

Syntax:

/endpoint/?field_name__exists=true /endpoint/?field_name__exists=false

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_gt(queryset, options, value)[source]

Apply gt functional query.

Syntax:

/endpoint/?field_name__gt={value}__{boost} /endpoint/?field_name__gt={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_gte(queryset, options, value)[source]

Apply gte functional query.

Syntax:

/endpoint/?field_name__gte={value}__{boost} /endpoint/?field_name__gte={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_in(queryset, options, value)[source]

Apply in functional query.

Syntax:

/endpoint/?field_name__in={value1}__{value2} /endpoint/?field_name__in={value1}

Note, that number of values is not limited.

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_isnull(queryset, options, value)[source]

Apply isnull functional query.

Syntax:

/endpoint/?field_name__isnull=true /endpoint/?field_name__isnull=false

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_lt(queryset, options, value)[source]

Apply lt functional query.

Syntax:

/endpoint/?field_name__lt={value}__{boost} /endpoint/?field_name__lt={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_lte(queryset, options, value)[source]

Apply lte functional query.

Syntax:

/endpoint/?field_name__lte={value}__{boost} /endpoint/?field_name__lte={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_wildcard(queryset, options, value)[source]

Apply wildcard filter.

Syntax:

/endpoint/?field_name__wildcard={value}* /endpoint/?field_name__wildcard=*{value} /endpoint/?field_name__wildcard=*{value}*

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_coreschema_field(field)[source]
get_filter_query_params(request, view)[source]

Get query params to be filtered on.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod get_gte_lte_params(value, lookup)[source]

Get params for gte, gt, lte and lt query.

Syntax:

/endpoint/?field_name__gt={lower}__{boost} /endpoint/?field_name__gt={lower}

Example:

Parameters:
  • value (str) –
  • lookup (str) –
Returns:

Params to be used in range query.

Return type:

dict

classmethod get_range_params(value)[source]

Get params for range query.

Syntax:

/endpoint/?field_name__range={lower}__{upper}__{boost} /endpoint/?field_name__range={lower}__{upper}

Example:

Parameters:value
Type:str
Returns:Params to be used in range query.
Return type:dict
get_schema_fields(view)[source]
classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
django_elasticsearch_dsl_drf.filter_backends.filtering.geo_spatial module

Geo spatial filtering backend.

Elasticsearch supports two types of geo data:

  • geo_point fields which support lat/lon pairs
  • geo_shape fields, which support points, lines, circles, polygons, multi-polygons etc.

The queries in this group are:

  • geo_shape query: Find document with geo-shapes which either intersect, are contained by, or do not intersect with the specified geo-shape.
  • geo_bounding_box query: Finds documents with geo-points that fall into the specified rectangle.
  • geo_distance query: Finds document with geo-points within the specified distance of a central point.
  • geo_distance_range query: Like the geo_distance query, but the range starts at a specified distance from the central point. Note, that this one is deprecated and this isn’t implemented.
  • geo_polygon query: Find documents with geo-points within the specified polygon.
class django_elasticsearch_dsl_drf.filter_backends.filtering.geo_spatial.GeoSpatialFilteringFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Geo-spatial filtering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_GEO_DISTANCE,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     GeoSpatialFilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [GeoSpatialFilteringFilterBackend,]
>>>     geo_spatial_filter_fields = {
>>>         'loc': 'location',
>>>         'location': {
>>>             'field': 'location',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_GEO_DISTANCE,
>>>             ],
>>>         }
>>> }
classmethod apply_query_geo_bounding_box(queryset, options, value)[source]

Apply geo_bounding_box query.

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_geo_distance(queryset, options, value)[source]

Apply geo_distance query.

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_geo_polygon(queryset, options, value)[source]

Apply geo_polygon query.

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_filter_query_params(request, view)[source]

Get query params to be filtered on.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod get_geo_bounding_box_params(value, field)[source]

Get params for geo_bounding_box query.

Example:

/api/articles/?location__geo_bounding_box=40.73,-74.1__40.01,-71.12

Example:

/api/articles/?location__geo_polygon=40.73,-74.1
__40.01,-71.12 ___name,myname __validation_method,IGNORE_MALFORMED __type,indexed

Elasticsearch:

{
“query”: {
“bool” : {
“must” : {
“match_all” : {}

}, “filter” : {

“geo_bounding_box” : {
“person.location” : {
“top_left” : {
“lat” : 40.73, “lon” : -74.1

}, “bottom_right” : {

“lat” : 40.01, “lon” : -71.12

}

}

}

}

}

}

}

Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_bounding_box query.

Return type:

dict

classmethod get_geo_distance_params(value, field)[source]

Get params for geo_distance query.

Example:

/api/articles/?location__geo_distance=2km__43.53__-12.23
Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_distance query.

Return type:

dict

classmethod get_geo_polygon_params(value, field)[source]

Get params for geo_polygon query.

Example:

/api/articles/?location__geo_polygon=40,-70__30,-80__20,-90

Example:

/api/articles/?location__geo_polygon=40,-70
__30,-80 __20,-90 ___name,myname __validation_method,IGNORE_MALFORMED

Elasticsearch:

{
“query”: {
“bool” : {
“must” : {
“match_all” : {}

}, “filter” : {

“geo_polygon” : {
“person.location” : {
“points” : [
{“lat” : 40, “lon” : -70}, {“lat” : 30, “lon” : -80}, {“lat” : 20, “lon” : -90}

]

}

}

}

}

}

}

Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_distance query.

Return type:

dict

classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
django_elasticsearch_dsl_drf.filter_backends.filtering.ids module

Ids filtering backend.

Filters documents that only have the provided ids. Note, this query uses the _uid field.

Elastic query:

{
“query”: {
“ids”: {
“type”: “book_document”, “values”: [“68”, “64”, “58”]

}

}

}

REST framework request equivalent:

Official Elastic docs:

class django_elasticsearch_dsl_drf.filter_backends.filtering.ids.IdsFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Ids filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     IdsFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [IdsFilterBackend]
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_ids_query_params(request)[source]

Get search query params.

Parameters:request (rest_framework.request.Request) – Django REST framework request.
Returns:List of search query params.
Return type:list
get_ids_values(request, view)[source]

Get ids values for query.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

ids_query_param = 'ids'
django_elasticsearch_dsl_drf.filter_backends.filtering.nested module

Nested filtering backend.

class django_elasticsearch_dsl_drf.filter_backends.filtering.nested.NestedFilteringFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.filtering.common.FilteringFilterBackend

Nested filter backend.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_TERM,
>>>     LOOKUP_FILTER_PREFIX,
>>>     LOOKUP_FILTER_WILDCARD,
>>>     LOOKUP_QUERY_EXCLUDE,
>>>     LOOKUP_QUERY_ISNULL,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     NestedFilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [NestedFilteringFilterBackend,]
>>>     nested_filter_fields = {
>>>         'country': {
>>>             'field': 'continent.country.name.raw',
>>>             'path': 'continent.country',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_TERM,
>>>                 LOOKUP_FILTER_TERMS,
>>>                 LOOKUP_FILTER_PREFIX,
>>>                 LOOKUP_FILTER_WILDCARD,
>>>                 LOOKUP_QUERY_EXCLUDE,
>>>                 LOOKUP_QUERY_ISNULL,
>>>             ],
>>>         }
>>> }
classmethod apply_filter(queryset, options=None, args=None, kwargs=None)[source]

Apply filter.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

classmethod apply_query(queryset, options=None, args=None, kwargs=None)[source]

Apply query.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

get_coreschema_field(field)[source]
get_filter_field_nested_path(filter_fields, field_name)[source]

Get filter field path to be used in nested query.

Parameters:
  • filter_fields
  • field_name
Returns:

get_filter_query_params(request, view)[source]

Get query params to be filtered on.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

get_schema_fields(view)[source]
classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
django_elasticsearch_dsl_drf.filter_backends.filtering.post_filter module

The post_filter filtering backend.

class django_elasticsearch_dsl_drf.filter_backends.filtering.post_filter.PostFilterFilteringFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.filtering.common.FilteringFilterBackend

The post_filter filtering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_PREFIX,
>>>     LOOKUP_FILTER_WILDCARD,
>>>     LOOKUP_QUERY_EXCLUDE,
>>>     LOOKUP_QUERY_ISNULL,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     PostFilterFilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [PostFilterFilteringFilterBackend,]
>>>     post_filter_fields = {
>>>         'title': 'title.raw',
>>>         'state': {
>>>             'field': 'state.raw',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_PREFIX,
>>>                 LOOKUP_FILTER_WILDCARD,
>>>                 LOOKUP_QUERY_EXCLUDE,
>>>                 LOOKUP_QUERY_ISNULL,
>>>             ],
>>>         }
>>> }
classmethod apply_filter(queryset, options=None, args=None, kwargs=None)[source]

Apply filter.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

classmethod apply_query(queryset, options=None, args=None, kwargs=None)[source]

Apply query.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

get_coreschema_field(field)[source]
get_schema_fields(view)[source]
classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
Module contents

Term level filtering and post_filter backends.

class django_elasticsearch_dsl_drf.filter_backends.filtering.FilteringFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Filtering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_PREFIX,
>>>     LOOKUP_FILTER_WILDCARD,
>>>     LOOKUP_QUERY_EXCLUDE,
>>>     LOOKUP_QUERY_ISNULL,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     FilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [FilteringFilterBackend,]
>>>     filter_fields = {
>>>         'title': 'title.raw',
>>>         'state': {
>>>             'field': 'state.raw',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_PREFIX,
>>>                 LOOKUP_FILTER_WILDCARD,
>>>                 LOOKUP_QUERY_EXCLUDE,
>>>                 LOOKUP_QUERY_ISNULL,
>>>             ],
>>>             'default_lookup': LOOKUP_FILTER_WILDCARD,
>>>         }
>>> }
classmethod apply_filter_prefix(queryset, options, value)[source]

Apply prefix filter.

Syntax:

/endpoint/?field_name__prefix={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_filter_range(queryset, options, value)[source]

Apply range filter.

Syntax:

/endpoint/?field_name__range={lower}__{upper}__{boost} /endpoint/?field_name__range={lower}__{upper}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_filter_term(queryset, options, value)[source]

Apply term filter.

Syntax:

/endpoint/?field_name={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_filter_terms(queryset, options, value)[source]

Apply terms filter.

Syntax:

/endpoint/?field_name__terms={value1}__{value2} /endpoint/?field_name__terms={value1}

Note, that number of values is not limited.

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (mixed: either str or iterable (list, tuple)) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_contains(queryset, options, value)[source]

Apply contains filter.

Syntax:

/endpoint/?field_name__contains={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_endswith(queryset, options, value)[source]

Apply endswith filter.

Syntax:

/endpoint/?field_name__endswith={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_exclude(queryset, options, value)[source]

Apply exclude functional query.

Syntax:

/endpoint/?field_name__isnull={value1}__{value2} /endpoint/?field_name__exclude={valu1}

Note, that number of values is not limited.

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_exists(queryset, options, value)[source]

Apply exists filter.

Syntax:

/endpoint/?field_name__exists=true /endpoint/?field_name__exists=false

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_gt(queryset, options, value)[source]

Apply gt functional query.

Syntax:

/endpoint/?field_name__gt={value}__{boost} /endpoint/?field_name__gt={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_gte(queryset, options, value)[source]

Apply gte functional query.

Syntax:

/endpoint/?field_name__gte={value}__{boost} /endpoint/?field_name__gte={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_in(queryset, options, value)[source]

Apply in functional query.

Syntax:

/endpoint/?field_name__in={value1}__{value2} /endpoint/?field_name__in={value1}

Note, that number of values is not limited.

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_isnull(queryset, options, value)[source]

Apply isnull functional query.

Syntax:

/endpoint/?field_name__isnull=true /endpoint/?field_name__isnull=false

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_lt(queryset, options, value)[source]

Apply lt functional query.

Syntax:

/endpoint/?field_name__lt={value}__{boost} /endpoint/?field_name__lt={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_lte(queryset, options, value)[source]

Apply lte functional query.

Syntax:

/endpoint/?field_name__lte={value}__{boost} /endpoint/?field_name__lte={value}

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_wildcard(queryset, options, value)[source]

Apply wildcard filter.

Syntax:

/endpoint/?field_name__wildcard={value}* /endpoint/?field_name__wildcard=*{value} /endpoint/?field_name__wildcard=*{value}*

Example:

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_coreschema_field(field)[source]
get_filter_query_params(request, view)[source]

Get query params to be filtered on.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod get_gte_lte_params(value, lookup)[source]

Get params for gte, gt, lte and lt query.

Syntax:

/endpoint/?field_name__gt={lower}__{boost} /endpoint/?field_name__gt={lower}

Example:

Parameters:
  • value (str) –
  • lookup (str) –
Returns:

Params to be used in range query.

Return type:

dict

classmethod get_range_params(value)[source]

Get params for range query.

Syntax:

/endpoint/?field_name__range={lower}__{upper}__{boost} /endpoint/?field_name__range={lower}__{upper}

Example:

Parameters:value
Type:str
Returns:Params to be used in range query.
Return type:dict
get_schema_fields(view)[source]
classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
class django_elasticsearch_dsl_drf.filter_backends.filtering.GeoSpatialFilteringFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Geo-spatial filtering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_GEO_DISTANCE,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     GeoSpatialFilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [GeoSpatialFilteringFilterBackend,]
>>>     geo_spatial_filter_fields = {
>>>         'loc': 'location',
>>>         'location': {
>>>             'field': 'location',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_GEO_DISTANCE,
>>>             ],
>>>         }
>>> }
classmethod apply_query_geo_bounding_box(queryset, options, value)[source]

Apply geo_bounding_box query.

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_geo_distance(queryset, options, value)[source]

Apply geo_distance query.

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_query_geo_polygon(queryset, options, value)[source]

Apply geo_polygon query.

Parameters:
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_filter_query_params(request, view)[source]

Get query params to be filtered on.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod get_geo_bounding_box_params(value, field)[source]

Get params for geo_bounding_box query.

Example:

/api/articles/?location__geo_bounding_box=40.73,-74.1__40.01,-71.12

Example:

/api/articles/?location__geo_polygon=40.73,-74.1
__40.01,-71.12 ___name,myname __validation_method,IGNORE_MALFORMED __type,indexed

Elasticsearch:

{
“query”: {
“bool” : {
“must” : {
“match_all” : {}

}, “filter” : {

“geo_bounding_box” : {
“person.location” : {
“top_left” : {
“lat” : 40.73, “lon” : -74.1

}, “bottom_right” : {

“lat” : 40.01, “lon” : -71.12

}

}

}

}

}

}

}

Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_bounding_box query.

Return type:

dict

classmethod get_geo_distance_params(value, field)[source]

Get params for geo_distance query.

Example:

/api/articles/?location__geo_distance=2km__43.53__-12.23
Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_distance query.

Return type:

dict

classmethod get_geo_polygon_params(value, field)[source]

Get params for geo_polygon query.

Example:

/api/articles/?location__geo_polygon=40,-70__30,-80__20,-90

Example:

/api/articles/?location__geo_polygon=40,-70
__30,-80 __20,-90 ___name,myname __validation_method,IGNORE_MALFORMED

Elasticsearch:

{
“query”: {
“bool” : {
“must” : {
“match_all” : {}

}, “filter” : {

“geo_polygon” : {
“person.location” : {
“points” : [
{“lat” : 40, “lon” : -70}, {“lat” : 30, “lon” : -80}, {“lat” : 20, “lon” : -90}

]

}

}

}

}

}

}

Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_distance query.

Return type:

dict

classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
class django_elasticsearch_dsl_drf.filter_backends.filtering.IdsFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Ids filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     IdsFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [IdsFilterBackend]
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_ids_query_params(request)[source]

Get search query params.

Parameters:request (rest_framework.request.Request) – Django REST framework request.
Returns:List of search query params.
Return type:list
get_ids_values(request, view)[source]

Get ids values for query.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

ids_query_param = 'ids'
class django_elasticsearch_dsl_drf.filter_backends.filtering.NestedFilteringFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.filtering.common.FilteringFilterBackend

Nested filter backend.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_TERM,
>>>     LOOKUP_FILTER_PREFIX,
>>>     LOOKUP_FILTER_WILDCARD,
>>>     LOOKUP_QUERY_EXCLUDE,
>>>     LOOKUP_QUERY_ISNULL,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     NestedFilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [NestedFilteringFilterBackend,]
>>>     nested_filter_fields = {
>>>         'country': {
>>>             'field': 'continent.country.name.raw',
>>>             'path': 'continent.country',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_TERM,
>>>                 LOOKUP_FILTER_TERMS,
>>>                 LOOKUP_FILTER_PREFIX,
>>>                 LOOKUP_FILTER_WILDCARD,
>>>                 LOOKUP_QUERY_EXCLUDE,
>>>                 LOOKUP_QUERY_ISNULL,
>>>             ],
>>>         }
>>> }
classmethod apply_filter(queryset, options=None, args=None, kwargs=None)[source]

Apply filter.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

classmethod apply_query(queryset, options=None, args=None, kwargs=None)[source]

Apply query.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

get_coreschema_field(field)[source]
get_filter_field_nested_path(filter_fields, field_name)[source]

Get filter field path to be used in nested query.

Parameters:
  • filter_fields
  • field_name
Returns:

get_filter_query_params(request, view)[source]

Get query params to be filtered on.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

get_schema_fields(view)[source]
classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
class django_elasticsearch_dsl_drf.filter_backends.filtering.PostFilterFilteringFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.filtering.common.FilteringFilterBackend

The post_filter filtering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     LOOKUP_FILTER_PREFIX,
>>>     LOOKUP_FILTER_WILDCARD,
>>>     LOOKUP_QUERY_EXCLUDE,
>>>     LOOKUP_QUERY_ISNULL,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     PostFilterFilteringFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [PostFilterFilteringFilterBackend,]
>>>     post_filter_fields = {
>>>         'title': 'title.raw',
>>>         'state': {
>>>             'field': 'state.raw',
>>>             'lookups': [
>>>                 LOOKUP_FILTER_PREFIX,
>>>                 LOOKUP_FILTER_WILDCARD,
>>>                 LOOKUP_QUERY_EXCLUDE,
>>>                 LOOKUP_QUERY_ISNULL,
>>>             ],
>>>         }
>>> }
classmethod apply_filter(queryset, options=None, args=None, kwargs=None)[source]

Apply filter.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

classmethod apply_query(queryset, options=None, args=None, kwargs=None)[source]

Apply query.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

get_coreschema_field(field)[source]
get_schema_fields(view)[source]
classmethod prepare_filter_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
django_elasticsearch_dsl_drf.filter_backends.ordering package
Submodules
django_elasticsearch_dsl_drf.filter_backends.ordering.common module

Ordering backend.

class django_elasticsearch_dsl_drf.filter_backends.ordering.common.DefaultOrderingFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.ordering.common.OrderingMixin

Default ordering filter backend for Elasticsearch.

Make sure this is your last ordering backend.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     DefaultOrderingFilterBackend,
>>>     OrderingFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [
>>>         DefaultOrderingFilterBackend,
>>>         OrderingFilterBackend,
>>>     ]
>>>     ordering_fields = {
>>>         'id': None,
>>>         'title': 'title.raw',
>>>         'date_submitted': 'date_submitted',
>>>         'continent': {
>>>             'field': 'continent.name.raw',
>>>             'path': 'continent',
>>>         }
>>>         'country': {
>>>             'field': 'continent.country.name.raw',
>>>             'path': 'continent.country',
>>>         }
>>>         'city': {
>>>             'field': 'continent.country.city.name.raw',
>>>             'path': 'continent.country.city',
>>>         }
>>>     }
>>>     ordering = 'city'
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod get_default_ordering_params(view)[source]

Get the default ordering params for the view.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:Ordering params to be used for ordering.
Return type:list
get_ordering_query_params(request, view)[source]

Get ordering query params.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Ordering params to be used for ordering.

Return type:

list

ordering_param = 'ordering'
class django_elasticsearch_dsl_drf.filter_backends.ordering.common.OrderingFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.ordering.common.OrderingMixin

Ordering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     OrderingFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [OrderingFilterBackend,]
>>>     ordering_fields = {
>>>         'id': None,
>>>         'title': 'title.raw',
>>>         'date_submitted': 'date_submitted',
>>>         'continent': {
>>>             'field': 'continent.name.raw',
>>>             'path': 'continent',
>>>         }
>>>         'country': {
>>>             'field': 'continent.country.name.raw',
>>>             'path': 'continent.country',
>>>         }
>>>         'city': {
>>>             'field': 'continent.country.city.name.raw',
>>>             'path': 'continent.country.city',
>>>         }
>>>     }
>>>     ordering = ('id', 'title',)
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_ordering_query_params(request, view)[source]

Get ordering query params.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Ordering params to be used for ordering.

Return type:

list

get_schema_fields(view)[source]
ordering_param = 'ordering'
django_elasticsearch_dsl_drf.filter_backends.ordering.geo_spatial module

Geo-spatial ordering backend.

class django_elasticsearch_dsl_drf.filter_backends.ordering.geo_spatial.GeoSpatialOrderingFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Geo-spatial ordering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     GeoSpatialOrderingFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [GeoSpatialOrderingFilterBackend,]
>>>     geo_spatial_ordering_fields = {
>>>         'location': {
>>>             'field': 'location',
>>>         }
>>>     }
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod get_geo_distance_params(value, field)[source]

Get params for geo_distance ordering.

Example:

/api/articles/?ordering=-location__45.3214__-34.3421__km__planes
Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_distance query.

Return type:

dict

get_geo_spatial_field_name(request, view, name)[source]

Get geo-spatial field name.

We have to deal with a couple of situations here:

Example 1:

>>> geo_spatial_ordering_fields = {
>>>     'location': None,
>>> }

Example 2:

>>> geo_spatial_ordering_fields = {
>>>     'location': 'location',
>>> }

Example 3:

>>> geo_spatial_ordering_fields = {
>>>     'location': {
>>>         'field': 'location'
>>>     },
>>> }
Parameters:
  • request
  • view
  • name
Returns:

get_ordering_query_params(request, view)[source]

Get ordering query params.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Ordering params to be used for ordering.

Return type:

list

ordering_param = 'ordering'
Module contents

Ordering backends.

class django_elasticsearch_dsl_drf.filter_backends.ordering.DefaultOrderingFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.ordering.common.OrderingMixin

Default ordering filter backend for Elasticsearch.

Make sure this is your last ordering backend.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     DefaultOrderingFilterBackend,
>>>     OrderingFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [
>>>         DefaultOrderingFilterBackend,
>>>         OrderingFilterBackend,
>>>     ]
>>>     ordering_fields = {
>>>         'id': None,
>>>         'title': 'title.raw',
>>>         'date_submitted': 'date_submitted',
>>>         'continent': {
>>>             'field': 'continent.name.raw',
>>>             'path': 'continent',
>>>         }
>>>         'country': {
>>>             'field': 'continent.country.name.raw',
>>>             'path': 'continent.country',
>>>         }
>>>         'city': {
>>>             'field': 'continent.country.city.name.raw',
>>>             'path': 'continent.country.city',
>>>         }
>>>     }
>>>     ordering = 'city'
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod get_default_ordering_params(view)[source]

Get the default ordering params for the view.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:Ordering params to be used for ordering.
Return type:list
get_ordering_query_params(request, view)[source]

Get ordering query params.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Ordering params to be used for ordering.

Return type:

list

ordering_param = 'ordering'
class django_elasticsearch_dsl_drf.filter_backends.ordering.GeoSpatialOrderingFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Geo-spatial ordering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     GeoSpatialOrderingFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [GeoSpatialOrderingFilterBackend,]
>>>     geo_spatial_ordering_fields = {
>>>         'location': {
>>>             'field': 'location',
>>>         }
>>>     }
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod get_geo_distance_params(value, field)[source]

Get params for geo_distance ordering.

Example:

/api/articles/?ordering=-location__45.3214__-34.3421__km__planes
Parameters:
  • value (str) –
  • field
Returns:

Params to be used in geo_distance query.

Return type:

dict

get_geo_spatial_field_name(request, view, name)[source]

Get geo-spatial field name.

We have to deal with a couple of situations here:

Example 1:

>>> geo_spatial_ordering_fields = {
>>>     'location': None,
>>> }

Example 2:

>>> geo_spatial_ordering_fields = {
>>>     'location': 'location',
>>> }

Example 3:

>>> geo_spatial_ordering_fields = {
>>>     'location': {
>>>         'field': 'location'
>>>     },
>>> }
Parameters:
  • request
  • view
  • name
Returns:

get_ordering_query_params(request, view)[source]

Get ordering query params.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Ordering params to be used for ordering.

Return type:

list

ordering_param = 'ordering'
class django_elasticsearch_dsl_drf.filter_backends.ordering.OrderingFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.ordering.common.OrderingMixin

Ordering filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     OrderingFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [OrderingFilterBackend,]
>>>     ordering_fields = {
>>>         'id': None,
>>>         'title': 'title.raw',
>>>         'date_submitted': 'date_submitted',
>>>         'continent': {
>>>             'field': 'continent.name.raw',
>>>             'path': 'continent',
>>>         }
>>>         'country': {
>>>             'field': 'continent.country.name.raw',
>>>             'path': 'continent.country',
>>>         }
>>>         'city': {
>>>             'field': 'continent.country.city.name.raw',
>>>             'path': 'continent.country.city',
>>>         }
>>>     }
>>>     ordering = ('id', 'title',)
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_ordering_query_params(request, view)[source]

Get ordering query params.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Ordering params to be used for ordering.

Return type:

list

get_schema_fields(view)[source]
ordering_param = 'ordering'
django_elasticsearch_dsl_drf.filter_backends.search package
Subpackages
django_elasticsearch_dsl_drf.filter_backends.search.query_backends package
Submodules
django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base module
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend[source]

Bases: object

Search query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match module
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match.MatchQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Match query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'match'
django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match_phrase module
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match_phrase.MatchPhraseQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Match phrase query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'match_phrase'
django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match_phrase_prefix module
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match_phrase_prefix.MatchPhrasePrefixQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Match phrase prefix query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'match_phrase_prefix'
django_elasticsearch_dsl_drf.filter_backends.search.query_backends.multi_match module
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.multi_match.MultiMatchQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Multi match query backend.

Construct search.

In case of multi match, we always look in a group of fields. Thus, matching per field is no longer valid use case here. However, we might want to have multiple fields enabled for multi match per view set, and only search in some of them in specific request.

Example:

/search/books/?search_multi_match=lorem ipsum /search/books/?search_multi_match=title,summary:lorem ipsum

Note, that multiple searches are not supported (would not raise an exception, but would simply take only the first):

/search/books/?search_multi_match=title,summary:lorem ipsum
&search_multi_match=author,publisher=o’reily

In the view-set fields shall be defined in a very simple way. The only accepted argument would be boost (per field).

Example 1 (complex):

multi_match_search_fields = {
‘title’: {‘field’: ‘title.english’, ‘boost’: 4}, ‘summary’: {‘boost’: 2}, ‘description’: None,

}

Example 2 (simple list):

multi_match_search_fields = (
‘title’, ‘summary’, ‘description’,

)

Parameters:
  • request
  • view
  • search_backend
Returns:

classmethod get_field(field, options)[source]

Get field.

Parameters:
  • field
  • options
Returns:

classmethod get_query_options(request, view, search_backend)[source]
query_type = 'multi_match'
django_elasticsearch_dsl_drf.filter_backends.search.query_backends.nested module
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.nested.NestedQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Nested query backend.

Construct search.

Dictionary key is the GET param name. The path option stands for the path in Elasticsearch.

Type 1:

search_nested_fields = {
‘country’: {
‘path’: ‘country’, ‘fields’: [‘name’],

}, ‘city’: {

‘path’: ‘country.city’, ‘fields’: [‘name’],

},

}

Type 2:

search_nested_fields = {
‘country’: {
‘path’: ‘country’, ‘fields’: [{‘name’: {‘boost’: 2}}]

}, ‘city’: {

‘path’: ‘country.city’, ‘fields’: [{‘name’: {‘boost’: 2}}]

},

}

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'nested'
django_elasticsearch_dsl_drf.filter_backends.search.query_backends.simple_query_string module
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.simple_query_string.SimpleQueryStringQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Simple query string query backend.

Construct search.

In case of multi match, we always look in a group of fields. Thus, matching per field is no longer valid use case here. However, we might want to have multiple fields enabled for multi match per view set, and only search in some of them in specific request.

Example:

/search/books/?search_simple_query_string=
“fried eggs” %2B(eggplant | potato) -frittata
/search/books/?search_simple_query_string=
title,summary:”fried eggs” +(eggplant | potato) -frittata

Note, that multiple searches are not supported (would not raise an exception, but would simply take only the first):

/search/books/?search_simple_query_string=
title,summary:”fried eggs” +(eggplant | potato) -frittata &search_simple_query_string= author,publisher=”fried eggs” +(eggplant | potato) -frittata

In the view-set fields shall be defined in a very simple way. The only accepted argument would be boost (per field).

Example 1 (complex):

simple_query_string_search_fields = {
‘title’: {‘field’: ‘title.english’, ‘boost’: 4}, ‘summary’: {‘boost’: 2}, ‘description’: None,

}

Example 2 (simple list):

simple_query_string_search_fields = (
‘title’, ‘summary’, ‘description’,

)

Query examples:

http://localhost:8000/search
/books-simple-query-string-search-backend /?search_simple_query_string=%22Pool%20of%20Tears%22
http://localhost:8000/search
/books-simple-query-string-search-backend /?search_simple_query_string=%22Pool%20of%20Tears%22 -considering
Parameters:
  • request
  • view
  • search_backend
Returns:

classmethod get_field(field, options)[source]

Get field.

Parameters:
  • field
  • options
Returns:

classmethod get_query_options(request, view, search_backend)[source]
query_type = 'simple_query_string'
Module contents

Search query backends.

class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.BaseSearchQueryBackend[source]

Bases: object

Search query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.MatchQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Match query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'match'
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.MatchPhraseQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Match phrase query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'match_phrase'
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.MatchPhrasePrefixQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Match phrase prefix query backend.

Construct search.

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'match_phrase_prefix'
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.MultiMatchQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Multi match query backend.

Construct search.

In case of multi match, we always look in a group of fields. Thus, matching per field is no longer valid use case here. However, we might want to have multiple fields enabled for multi match per view set, and only search in some of them in specific request.

Example:

/search/books/?search_multi_match=lorem ipsum /search/books/?search_multi_match=title,summary:lorem ipsum

Note, that multiple searches are not supported (would not raise an exception, but would simply take only the first):

/search/books/?search_multi_match=title,summary:lorem ipsum
&search_multi_match=author,publisher=o’reily

In the view-set fields shall be defined in a very simple way. The only accepted argument would be boost (per field).

Example 1 (complex):

multi_match_search_fields = {
‘title’: {‘field’: ‘title.english’, ‘boost’: 4}, ‘summary’: {‘boost’: 2}, ‘description’: None,

}

Example 2 (simple list):

multi_match_search_fields = (
‘title’, ‘summary’, ‘description’,

)

Parameters:
  • request
  • view
  • search_backend
Returns:

classmethod get_field(field, options)[source]

Get field.

Parameters:
  • field
  • options
Returns:

classmethod get_query_options(request, view, search_backend)[source]
query_type = 'multi_match'
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.NestedQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Nested query backend.

Construct search.

Dictionary key is the GET param name. The path option stands for the path in Elasticsearch.

Type 1:

search_nested_fields = {
‘country’: {
‘path’: ‘country’, ‘fields’: [‘name’],

}, ‘city’: {

‘path’: ‘country.city’, ‘fields’: [‘name’],

},

}

Type 2:

search_nested_fields = {
‘country’: {
‘path’: ‘country’, ‘fields’: [{‘name’: {‘boost’: 2}}]

}, ‘city’: {

‘path’: ‘country.city’, ‘fields’: [{‘name’: {‘boost’: 2}}]

},

}

Parameters:
  • request
  • view
  • search_backend
Returns:

query_type = 'nested'
class django_elasticsearch_dsl_drf.filter_backends.search.query_backends.SimpleQueryStringQueryBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.query_backends.base.BaseSearchQueryBackend

Simple query string query backend.

Construct search.

In case of multi match, we always look in a group of fields. Thus, matching per field is no longer valid use case here. However, we might want to have multiple fields enabled for multi match per view set, and only search in some of them in specific request.

Example:

/search/books/?search_simple_query_string=
“fried eggs” %2B(eggplant | potato) -frittata
/search/books/?search_simple_query_string=
title,summary:”fried eggs” +(eggplant | potato) -frittata

Note, that multiple searches are not supported (would not raise an exception, but would simply take only the first):

/search/books/?search_simple_query_string=
title,summary:”fried eggs” +(eggplant | potato) -frittata &search_simple_query_string= author,publisher=”fried eggs” +(eggplant | potato) -frittata

In the view-set fields shall be defined in a very simple way. The only accepted argument would be boost (per field).

Example 1 (complex):

simple_query_string_search_fields = {
‘title’: {‘field’: ‘title.english’, ‘boost’: 4}, ‘summary’: {‘boost’: 2}, ‘description’: None,

}

Example 2 (simple list):

simple_query_string_search_fields = (
‘title’, ‘summary’, ‘description’,

)

Query examples:

http://localhost:8000/search
/books-simple-query-string-search-backend /?search_simple_query_string=%22Pool%20of%20Tears%22
http://localhost:8000/search
/books-simple-query-string-search-backend /?search_simple_query_string=%22Pool%20of%20Tears%22 -considering
Parameters:
  • request
  • view
  • search_backend
Returns:

classmethod get_field(field, options)[source]

Get field.

Parameters:
  • field
  • options
Returns:

classmethod get_query_options(request, view, search_backend)[source]
query_type = 'simple_query_string'
Submodules
django_elasticsearch_dsl_drf.filter_backends.search.base module

Base search backend.

class django_elasticsearch_dsl_drf.filter_backends.search.base.BaseSearchFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Base search filter backend.

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_coreschema_field(field)[source]
get_query_backends(request, view)[source]

Get query backends.

Returns:
get_schema_fields(view)[source]
get_search_query_params(request)[source]

Get search query params.

Parameters:request (rest_framework.request.Request) – Django REST framework request.
Returns:List of search query params.
Return type:list
matching = 'should'
query_backends = []
search_param = 'search'
django_elasticsearch_dsl_drf.filter_backends.search.compound module

Compound search backend.

class django_elasticsearch_dsl_drf.filter_backends.search.compound.CompoundSearchFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.base.BaseSearchFilterBackend

Compound search backend.

query_backends = [<class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match.MatchQueryBackend'>, <class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.nested.NestedQueryBackend'>]
django_elasticsearch_dsl_drf.filter_backends.search.historical module

Search backend. Most likely to be deprecated soon.

class django_elasticsearch_dsl_drf.filter_backends.search.historical.SearchFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Search filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     SearchFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [SearchFilterBackend,]
>>>     search_fields = (
>>>         'title',
>>>         'content',
>>>     )
>>>     search_nested_fields = {
>>>         'state': ['name'],
>>>         'documents.author': ['title', 'description'],
>>>     }

Construct nested search.

We have to deal with two types of structures:

Type 1:

>>> search_nested_fields = {
>>>     'country': {
>>>         'path': 'country',
>>>         'fields': ['name'],
>>>     },
>>>     'city': {
>>>         'path': 'country.city',
>>>         'fields': ['name'],
>>>     },
>>> }

Type 2:

>>> search_nested_fields = {
>>>     'country': {
>>>         'path': 'country',
>>>         'fields': [{'name': {'boost': 2}}]
>>>     },
>>>     'city': {
>>>         'path': 'country.city',
>>>         'fields': [{'name': {'boost': 2}}]
>>>     },
>>> }
Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

Construct search.

We have to deal with two types of structures:

Type 1:

>>> search_fields = (
>>>     'title',
>>>     'description',
>>>     'summary',
>>> )

Type 2:

>>> search_fields = {
>>>     'title': {'boost': 2},
>>>     'description': None,
>>>     'summary': None,
>>> }
Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_coreschema_field(field)[source]
get_schema_fields(view)[source]
get_search_query_params(request)[source]

Get search query params.

Parameters:request (rest_framework.request.Request) – Django REST framework request.
Returns:List of search query params.
Return type:list
search_param = 'search'
django_elasticsearch_dsl_drf.filter_backends.search.multi_match module

Multi match search filter backend.

class django_elasticsearch_dsl_drf.filter_backends.search.multi_match.MultiMatchSearchFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.base.BaseSearchFilterBackend

Multi match search filter backend.

matching = 'must'
query_backends = [<class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.multi_match.MultiMatchQueryBackend'>]
search_param = 'search_multi_match'
django_elasticsearch_dsl_drf.filter_backends.search.query_string module
django_elasticsearch_dsl_drf.filter_backends.search.simple_query_string module

Simple query string search filter backend.

class django_elasticsearch_dsl_drf.filter_backends.search.simple_query_string.SimpleQueryStringSearchFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.base.BaseSearchFilterBackend

Simple query string search filter backend.

matching = 'must'
query_backends = [<class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.simple_query_string.SimpleQueryStringQueryBackend'>]
search_param = 'search_simple_query_string'
Module contents

Search filter backends.

class django_elasticsearch_dsl_drf.filter_backends.search.BaseSearchFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Base search filter backend.

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_coreschema_field(field)[source]
get_query_backends(request, view)[source]

Get query backends.

Returns:
get_schema_fields(view)[source]
get_search_query_params(request)[source]

Get search query params.

Parameters:request (rest_framework.request.Request) – Django REST framework request.
Returns:List of search query params.
Return type:list
matching = 'should'
query_backends = []
search_param = 'search'
class django_elasticsearch_dsl_drf.filter_backends.search.CompoundSearchFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.base.BaseSearchFilterBackend

Compound search backend.

query_backends = [<class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.match.MatchQueryBackend'>, <class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.nested.NestedQueryBackend'>]
class django_elasticsearch_dsl_drf.filter_backends.search.MultiMatchSearchFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.base.BaseSearchFilterBackend

Multi match search filter backend.

matching = 'must'
query_backends = [<class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.multi_match.MultiMatchQueryBackend'>]
search_param = 'search_multi_match'
class django_elasticsearch_dsl_drf.filter_backends.search.SearchFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Search filter backend for Elasticsearch.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     SearchFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [SearchFilterBackend,]
>>>     search_fields = (
>>>         'title',
>>>         'content',
>>>     )
>>>     search_nested_fields = {
>>>         'state': ['name'],
>>>         'documents.author': ['title', 'description'],
>>>     }

Construct nested search.

We have to deal with two types of structures:

Type 1:

>>> search_nested_fields = {
>>>     'country': {
>>>         'path': 'country',
>>>         'fields': ['name'],
>>>     },
>>>     'city': {
>>>         'path': 'country.city',
>>>         'fields': ['name'],
>>>     },
>>> }

Type 2:

>>> search_nested_fields = {
>>>     'country': {
>>>         'path': 'country',
>>>         'fields': [{'name': {'boost': 2}}]
>>>     },
>>>     'city': {
>>>         'path': 'country.city',
>>>         'fields': [{'name': {'boost': 2}}]
>>>     },
>>> }
Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

Construct search.

We have to deal with two types of structures:

Type 1:

>>> search_fields = (
>>>     'title',
>>>     'description',
>>>     'summary',
>>> )

Type 2:

>>> search_fields = {
>>>     'title': {'boost': 2},
>>>     'description': None,
>>>     'summary': None,
>>> }
Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_coreschema_field(field)[source]
get_schema_fields(view)[source]
get_search_query_params(request)[source]

Get search query params.

Parameters:request (rest_framework.request.Request) – Django REST framework request.
Returns:List of search query params.
Return type:list
search_param = 'search'
class django_elasticsearch_dsl_drf.filter_backends.search.SimpleQueryStringSearchFilterBackend[source]

Bases: django_elasticsearch_dsl_drf.filter_backends.search.base.BaseSearchFilterBackend

Simple query string search filter backend.

matching = 'must'
query_backends = [<class 'django_elasticsearch_dsl_drf.filter_backends.search.query_backends.simple_query_string.SimpleQueryStringQueryBackend'>]
search_param = 'search_simple_query_string'
django_elasticsearch_dsl_drf.filter_backends.suggester package
Submodules
django_elasticsearch_dsl_drf.filter_backends.suggester.functional module

Functional suggesters backend.

It’s assumed, that fields you’re planning to query suggestions for have been properly indexed using fields.CompletionField.

Example:

>>> from django_elasticsearch_dsl import Document, Index, fields
>>>
>>> from books.models import Publisher
>>>
>>> # Name of the Elasticsearch index
>>> PUBLISHER_INDEX = Index(PUBLISHER_INDEX_NAME)
>>> # See Elasticsearch Indices API reference for available settings
>>> PUBLISHER_INDEX.settings(
>>>     number_of_shards=1,
>>>     number_of_replicas=1
>>> )
>>>
>>> @PUBLISHER_INDEX.doc_type
>>> class PublisherDocument(Document):
>>>     "Publisher Elasticsearch document."
>>>
>>>     id = fields.IntegerField(attr='id')
>>>
>>>     name = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     info = fields.StringField()
>>>
>>>     address = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword')
>>>         }
>>>     )
>>>
>>>     city = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     state_province = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     country = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     website = fields.StringField()
>>>
>>>     class Meta(object):
>>>         "Meta options."
>>>
>>>         model = Publisher  # The model associate with this Document
class django_elasticsearch_dsl_drf.filter_backends.suggester.functional.FunctionalSuggesterFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Suggester filter backend for Elasticsearch.

Suggestion functionality is exclusive. Once you have queried the FunctionalSuggesterFilterBackend, the latter will transform your current search query into another search query (altered). Therefore, always add it as the very last filter backend.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
>>>     FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>     FUNCTIONAL_SUGGESTER_PHRASE_MATCH,
>>>     FUNCTIONAL_SUGGESTER_PHRASE_MATCH,
>>>     FUNCTIONAL_SUGGESTER_TERM_MATCH,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     FunctionalSuggesterFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
>>>
>>> # Local PublisherDocument definition
>>> from .documents import PublisherDocument
>>>
>>> # Local PublisherDocument serializer
>>> from .serializers import PublisherDocumentSerializer
>>>
>>> class PublisherDocumentView(DocumentViewSet):
>>>
>>>     document = PublisherDocument
>>>     serializer_class = PublisherDocumentSerializer
>>>     filter_backends = [
>>>         # ...
>>>         FunctionalSuggesterFilterBackend,
>>>     ]
>>>     # Suggester fields
>>>     functional_suggester_fields = {
>>>         'name_suggest': {
>>>             'field': 'name.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>             ],
>>>         },
>>>         'city_suggest': {
>>>             'field': 'city.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>             ],
>>>         },
>>>         'state_province_suggest': {
>>>             'field': 'state_province.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
>>>             ],
>>>         },
>>>         'country_suggest': {
>>>             'field': 'country.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>             ],
>>>         },
>>>     }
classmethod apply_query_size(queryset, options)[source]

Apply query size.

Parameters:
  • queryset
  • options
Returns:

classmethod apply_suggester_completion_match(suggester_name, queryset, options, value)[source]

Apply completion suggester match.

This is effective when used with Ngram fields.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_suggester_completion_prefix(suggester_name, queryset, options, value)[source]

Apply completion suggester prefix.

This is effective when used with Keyword fields.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

clean_queryset(queryset)[source]

Clean the queryset.

  • Remove aggregations.
  • Remove highlight.
  • Remove sorting options.
Parameters:queryset
Returns:
extract_field_name(field_name)[source]

Extract field name.

For instance, “name.suggest” or “name.raw” becomes “name”.

Parameters:field_name
Returns:
Return type:str
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_suggester_query_params(request, view)[source]

Get query params to be for suggestions.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod prepare_suggester_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
serialize_queryset(queryset, suggester_name, value, serializer_field)[source]

Serialize queryset.

This shall be done here, since we don’t want to delegate it to pagination.

Parameters:
  • queryset
  • suggester_name
  • value
  • serializer_field
Returns:

django_elasticsearch_dsl_drf.filter_backends.suggester.native module

Suggesters backend.

It’s assumed, that fields you’re planning to query suggestions for have been properly indexed using fields.CompletionField.

Example:

>>> from django_elasticsearch_dsl import Document, Index, fields
>>>
>>> from books.models import Publisher
>>>
>>> # Name of the Elasticsearch index
>>> PUBLISHER_INDEX = Index(PUBLISHER_INDEX_NAME)
>>> # See Elasticsearch Indices API reference for available settings
>>> PUBLISHER_INDEX.settings(
>>>     number_of_shards=1,
>>>     number_of_replicas=1
>>> )
>>>
>>> @PUBLISHER_INDEX.doc_type
>>> class PublisherDocument(Document):
>>>     "Publisher Elasticsearch document."
>>>
>>>     id = fields.IntegerField(attr='id')
>>>
>>>     name = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     info = fields.StringField()
>>>
>>>     address = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword')
>>>         }
>>>     )
>>>
>>>     city = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     state_province = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     country = fields.StringField(
>>>         fields={
>>>             'raw': fields.StringField(analyzer='keyword'),
>>>             'suggest': fields.CompletionField(),
>>>         }
>>>     )
>>>
>>>     website = fields.StringField()
>>>
>>>     class Meta(object):
>>>         "Meta options."
>>>
>>>         model = Publisher  # The model associate with this Document
class django_elasticsearch_dsl_drf.filter_backends.suggester.native.SuggesterFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Suggester filter backend for Elasticsearch.

Suggestion functionality is exclusive. Once you have queried the SuggesterFilterBackend, the latter will transform your current search query into suggestion search query (which is very different). Therefore, always add it as the very last filter backend.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     SUGGESTER_TERM,
>>>     SUGGESTER_PHRASE,
>>>     SUGGESTER_COMPLETION,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     SuggesterFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
>>>
>>> # Local PublisherDocument definition
>>> from .documents import PublisherDocument
>>>
>>> # Local PublisherDocument serializer
>>> from .serializers import PublisherDocumentSerializer
>>>
>>> class PublisherDocumentView(BaseDocumentViewSet):
>>>
>>>     document = PublisherDocument
>>>     serializer_class = PublisherDocumentSerializer
>>>     filter_backends = [
>>>         # ...
>>>         SuggesterFilterBackend,
>>>     ]
>>>     # Suggester fields
>>>     suggester_fields = {
>>>         'name_suggest': {
>>>             'field': 'name.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_TERM,
>>>                 SUGGESTER_PHRASE,
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>         'city_suggest': {
>>>             'field': 'city.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>         'state_province_suggest': {
>>>             'field': 'state_province.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>         'country_suggest': {
>>>             'field': 'country.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>     }
classmethod apply_suggester_completion(suggester_name, queryset, options, value)[source]

Apply completion suggester.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_suggester_phrase(suggester_name, queryset, options, value)[source]

Apply phrase suggester.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_suggester_term(suggester_name, queryset, options, value)[source]

Apply term suggester.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod get_suggester_context(field, suggester_name, request, view)[source]

Get suggester context.

Given the following definition (in ViewSets):

>>> # Suggester fields
>>> suggester_fields = {
>>>     'title_suggest': {
>>>         'field': 'title.suggest',
>>>         'default_suggester': SUGGESTER_COMPLETION,
>>>     },
>>>     'title_suggest_context': {
>>>         'field': 'title.suggest_context',
>>>         'default_suggester': SUGGESTER_COMPLETION,
>>>         'completion_options': {
>>>             'filters': {
>>>                 'title_suggest_tag': 'tag',
>>>                 'title_suggest_state': 'state',
>>>                 'title_suggest_publisher': 'publisher',
>>>             },
>>>             'size': 10,
>>>         }
>>>     },
>>> }

http://localhost:8000/search/books-frontend/suggest/?title_suggest_context=M

When talking about the queries made, we have the following. Multiple values per field are combined with OR:

>>> completion={
>>>     'field': options['field'],
>>>     'size': 10,
>>>     'contexts': {
>>>         'tag': ['History', 'Drama'],
>>>     }
>>> }

The following works with OR as well, so it seems we have OR only. However, the following construction is more handy, since it allows us to play with boosting nicely. Also, it allows to provide prefix param (which in case of the example given below means that suggestions shall match both categories with “Child”, “Children”, “Childrend’s”). Simply put it’s treated as prefix, rather than term.

>>> completion={
>>>     'field': options['field'],
>>>     'size': 10,
>>>     'contexts': {
>>>         'tag': [
>>>             {'context': 'History'},
>>>             {'context': 'Drama', 'boost': 2},
>>>             {'context': 'Children', 'prefix': True},
>>>         ],
>>>     },
>>> }

Sample query for category filter:

/search/books-frontend/suggest/ ?title_suggest_context=M &title_suggest_tag=Art__2.0 &title_suggest_tag=Documentary__2.0__prefix &title_suggest_publisher=Apress

The query params would be:

query_params: <QueryDict: {

‘title_suggest_context’: [‘M’], ‘title_suggest_tag’: [‘Art__2.0’, ‘Documentary__2.0__prefix’], ‘title_suggest_publisher’: [‘Apress’]

}>

Sample query for geo filter:

/search/address/suggest/ ?street_suggest_context=M &street_suggest_loc=43.66__-79.22__2.0__10000km

The query params would be:

query_params: <QueryDict: {

‘street_suggest_context’: [‘M’], ‘street_suggest_loc’: [‘Art__43.66__-79.22__2.0__10000km’],

}>

Returns:
get_suggester_query_params(request, view)[source]

Get query params to be for suggestions.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod prepare_suggester_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
Module contents

Suggester filtering backends.

class django_elasticsearch_dsl_drf.filter_backends.suggester.SuggesterFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Suggester filter backend for Elasticsearch.

Suggestion functionality is exclusive. Once you have queried the SuggesterFilterBackend, the latter will transform your current search query into suggestion search query (which is very different). Therefore, always add it as the very last filter backend.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     SUGGESTER_TERM,
>>>     SUGGESTER_PHRASE,
>>>     SUGGESTER_COMPLETION,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     SuggesterFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
>>>
>>> # Local PublisherDocument definition
>>> from .documents import PublisherDocument
>>>
>>> # Local PublisherDocument serializer
>>> from .serializers import PublisherDocumentSerializer
>>>
>>> class PublisherDocumentView(BaseDocumentViewSet):
>>>
>>>     document = PublisherDocument
>>>     serializer_class = PublisherDocumentSerializer
>>>     filter_backends = [
>>>         # ...
>>>         SuggesterFilterBackend,
>>>     ]
>>>     # Suggester fields
>>>     suggester_fields = {
>>>         'name_suggest': {
>>>             'field': 'name.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_TERM,
>>>                 SUGGESTER_PHRASE,
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>         'city_suggest': {
>>>             'field': 'city.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>         'state_province_suggest': {
>>>             'field': 'state_province.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>         'country_suggest': {
>>>             'field': 'country.suggest',
>>>             'suggesters': [
>>>                 SUGGESTER_COMPLETION,
>>>             ],
>>>         },
>>>     }
classmethod apply_suggester_completion(suggester_name, queryset, options, value)[source]

Apply completion suggester.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_suggester_phrase(suggester_name, queryset, options, value)[source]

Apply phrase suggester.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_suggester_term(suggester_name, queryset, options, value)[source]

Apply term suggester.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod get_suggester_context(field, suggester_name, request, view)[source]

Get suggester context.

Given the following definition (in ViewSets):

>>> # Suggester fields
>>> suggester_fields = {
>>>     'title_suggest': {
>>>         'field': 'title.suggest',
>>>         'default_suggester': SUGGESTER_COMPLETION,
>>>     },
>>>     'title_suggest_context': {
>>>         'field': 'title.suggest_context',
>>>         'default_suggester': SUGGESTER_COMPLETION,
>>>         'completion_options': {
>>>             'filters': {
>>>                 'title_suggest_tag': 'tag',
>>>                 'title_suggest_state': 'state',
>>>                 'title_suggest_publisher': 'publisher',
>>>             },
>>>             'size': 10,
>>>         }
>>>     },
>>> }

http://localhost:8000/search/books-frontend/suggest/?title_suggest_context=M

When talking about the queries made, we have the following. Multiple values per field are combined with OR:

>>> completion={
>>>     'field': options['field'],
>>>     'size': 10,
>>>     'contexts': {
>>>         'tag': ['History', 'Drama'],
>>>     }
>>> }

The following works with OR as well, so it seems we have OR only. However, the following construction is more handy, since it allows us to play with boosting nicely. Also, it allows to provide prefix param (which in case of the example given below means that suggestions shall match both categories with “Child”, “Children”, “Childrend’s”). Simply put it’s treated as prefix, rather than term.

>>> completion={
>>>     'field': options['field'],
>>>     'size': 10,
>>>     'contexts': {
>>>         'tag': [
>>>             {'context': 'History'},
>>>             {'context': 'Drama', 'boost': 2},
>>>             {'context': 'Children', 'prefix': True},
>>>         ],
>>>     },
>>> }

Sample query for category filter:

/search/books-frontend/suggest/ ?title_suggest_context=M &title_suggest_tag=Art__2.0 &title_suggest_tag=Documentary__2.0__prefix &title_suggest_publisher=Apress

The query params would be:

query_params: <QueryDict: {

‘title_suggest_context’: [‘M’], ‘title_suggest_tag’: [‘Art__2.0’, ‘Documentary__2.0__prefix’], ‘title_suggest_publisher’: [‘Apress’]

}>

Sample query for geo filter:

/search/address/suggest/ ?street_suggest_context=M &street_suggest_loc=43.66__-79.22__2.0__10000km

The query params would be:

query_params: <QueryDict: {

‘street_suggest_context’: [‘M’], ‘street_suggest_loc’: [‘Art__43.66__-79.22__2.0__10000km’],

}>

Returns:
get_suggester_query_params(request, view)[source]

Get query params to be for suggestions.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod prepare_suggester_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
class django_elasticsearch_dsl_drf.filter_backends.suggester.FunctionalSuggesterFilterBackend[source]

Bases: rest_framework.filters.BaseFilterBackend, django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin

Suggester filter backend for Elasticsearch.

Suggestion functionality is exclusive. Once you have queried the FunctionalSuggesterFilterBackend, the latter will transform your current search query into another search query (altered). Therefore, always add it as the very last filter backend.

Example:

>>> from django_elasticsearch_dsl_drf.constants import (
>>>     FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
>>>     FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>     FUNCTIONAL_SUGGESTER_PHRASE_MATCH,
>>>     FUNCTIONAL_SUGGESTER_PHRASE_MATCH,
>>>     FUNCTIONAL_SUGGESTER_TERM_MATCH,
>>> )
>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     FunctionalSuggesterFilterBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
>>>
>>> # Local PublisherDocument definition
>>> from .documents import PublisherDocument
>>>
>>> # Local PublisherDocument serializer
>>> from .serializers import PublisherDocumentSerializer
>>>
>>> class PublisherDocumentView(DocumentViewSet):
>>>
>>>     document = PublisherDocument
>>>     serializer_class = PublisherDocumentSerializer
>>>     filter_backends = [
>>>         # ...
>>>         FunctionalSuggesterFilterBackend,
>>>     ]
>>>     # Suggester fields
>>>     functional_suggester_fields = {
>>>         'name_suggest': {
>>>             'field': 'name.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>             ],
>>>         },
>>>         'city_suggest': {
>>>             'field': 'city.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>             ],
>>>         },
>>>         'state_province_suggest': {
>>>             'field': 'state_province.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_MATCH,
>>>             ],
>>>         },
>>>         'country_suggest': {
>>>             'field': 'country.suggest',
>>>             'suggesters': [
>>>                 FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX,
>>>             ],
>>>         },
>>>     }
classmethod apply_query_size(queryset, options)[source]

Apply query size.

Parameters:
  • queryset
  • options
Returns:

classmethod apply_suggester_completion_match(suggester_name, queryset, options, value)[source]

Apply completion suggester match.

This is effective when used with Ngram fields.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

classmethod apply_suggester_completion_prefix(suggester_name, queryset, options, value)[source]

Apply completion suggester prefix.

This is effective when used with Keyword fields.

Parameters:
  • suggester_name (str) –
  • queryset (elasticsearch_dsl.search.Search) – Original queryset.
  • options (dict) – Filter options.
  • value (str) – value to filter on.
Returns:

Modified queryset.

Return type:

elasticsearch_dsl.search.Search

clean_queryset(queryset)[source]

Clean the queryset.

  • Remove aggregations.
  • Remove highlight.
  • Remove sorting options.
Parameters:queryset
Returns:
extract_field_name(field_name)[source]

Extract field name.

For instance, “name.suggest” or “name.raw” becomes “name”.

Parameters:field_name
Returns:
Return type:str
filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_suggester_query_params(request, view)[source]

Get query params to be for suggestions.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Request query params to filter on.

Return type:

dict

classmethod prepare_suggester_fields(view)[source]

Prepare filter fields.

Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Filtering options.
Return type:dict
serialize_queryset(queryset, suggester_name, value, serializer_field)[source]

Serialize queryset.

This shall be done here, since we don’t want to delegate it to pagination.

Parameters:
  • queryset
  • suggester_name
  • value
  • serializer_field
Returns:

Submodules
django_elasticsearch_dsl_drf.filter_backends.highlight module

Highlight backend.

class django_elasticsearch_dsl_drf.filter_backends.highlight.HighlightBackend[source]

Bases: rest_framework.filters.BaseFilterBackend

Highlight backend.

Example:

>>> from django_elasticsearch_dsl_drf.filter_backends import (
>>>     HighlightBackend
>>> )
>>> from django_elasticsearch_dsl_drf.viewsets import (
>>>     BaseDocumentViewSet,
>>> )
>>>
>>> # Local article document definition
>>> from .documents import ArticleDocument
>>>
>>> # Local article document serializer
>>> from .serializers import ArticleDocumentSerializer
>>>
>>> class ArticleDocumentView(BaseDocumentViewSet):
>>>
>>>     document = ArticleDocument
>>>     serializer_class = ArticleDocumentSerializer
>>>     filter_backends = [HighlightBackend,]
>>>     highlight_fields = {
>>>         'author.name': {
>>>             'enabled': False,
>>>             'options': {
>>>                 'fragment_size': 150,
>>>                 'number_of_fragments': 3
>>>             }
>>>         }
>>>         'title': {
>>>             'options': {
>>>                 'pre_tags' : ["<em>"],
>>>                 'post_tags' : ["</em>"]
>>>             },
>>>             'enabled': True,
>>>         },
>>>     }

Highlight make queries to be more heavy. That’s why by default all highlights are disabled and enabled only explicitly either in the filter options (enabled set to True) or via query params ?highlight=author.name&highlight=title.

filter_queryset(request, queryset, view)[source]

Filter the queryset.

Parameters:
  • request (rest_framework.request.Request) – Django REST framework request.
  • queryset (elasticsearch_dsl.search.Search) – Base queryset.
  • view (rest_framework.viewsets.ReadOnlyModelViewSet) – View.
Returns:

Updated queryset.

Return type:

elasticsearch_dsl.search.Search

get_highlight_query_params(request)[source]

Get highlight query params.

Parameters:request (rest_framework.request.Request) – Django REST framework request.
Returns:List of search query params.
Return type:list
highlight_param = 'highlight'
classmethod prepare_highlight_fields(view)[source]

Prepare faceted search fields.

Prepares the following structure:

>>> {
>>>     'author.name': {
>>>         'enabled': False,
>>>         'options': {
>>>             'fragment_size': 150,
>>>             'number_of_fragments': 3
>>>         }
>>>     }
>>>     'title': {
>>>         'options': {
>>>             'pre_tags' : ["<em>"],
>>>             'post_tags' : ["</em>"]
>>>         },
>>>         'enabled': True,
>>>     },
>>> }
Parameters:view (rest_framework.viewsets.ReadOnlyModelViewSet) –
Returns:Highlight fields options.
Return type:dict
django_elasticsearch_dsl_drf.filter_backends.mixins module

Mixins.

class django_elasticsearch_dsl_drf.filter_backends.mixins.FilterBackendMixin[source]

Bases: object

Filter backend mixin.

classmethod apply_filter(queryset, options=None, args=None, kwargs=None)[source]

Apply filter.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

classmethod apply_query(queryset, options=None, args=None, kwargs=None)[source]

Apply query.

Parameters:
  • queryset
  • options
  • args
  • kwargs
Returns:

classmethod split_lookup_complex_multiple_value(value, maxsplit=-1)[source]

Split lookup complex multiple value.

Parameters:
  • value (str) – Value to split.
  • maxsplit (int) – The maxsplit option of string.split.
Returns:

Lookup filter split into a list.

Return type:

list

classmethod split_lookup_complex_value(value, maxsplit=-1)[source]

Split lookup complex value.

Parameters:
  • value (str) – Value to split.
  • maxsplit (int) – The maxsplit option of string.split.
Returns:

Lookup filter split into a list.

Return type:

list

classmethod split_lookup_filter(value, maxsplit=-1)[source]

Split lookup filter.

Parameters:
  • value (str) – Value to split.
  • maxsplit (int) – The maxsplit option of string.split.
Returns:

Lookup filter split into a list.

Return type:

list

classmethod split_lookup_name(value, maxsplit=-1)[source]

Split lookup value.

Parameters:
  • value (str) – Value to split.
  • maxsplit (int) – The maxsplit option of string.split.
Returns:

Lookup value split into a list.

Return type:

list

Module contents

All filter backends.

django_elasticsearch_dsl_drf.tests package
Submodules
django_elasticsearch_dsl_drf.tests.base module

Base tests.

class django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase(methodName='runTest')[source]

Bases: django.test.testcases.TransactionTestCase

Base REST framework test case.

authenticate()[source]

Helper for logging in Genre Coordinator user.

Returns:
pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

class django_elasticsearch_dsl_drf.tests.base.BaseTestCase(methodName='runTest')[source]

Bases: django.test.testcases.TransactionTestCase

Base test case.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

django_elasticsearch_dsl_drf.tests.data_mixins module

Data mixins.

class django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin[source]

Bases: object

Addresses mixin.

classmethod created_addresses()[source]

Create addresses.

Returns:
class django_elasticsearch_dsl_drf.tests.data_mixins.BooksMixin[source]

Bases: object

Books mixin.

classmethod create_books()[source]

Create books.

Returns:
django_elasticsearch_dsl_drf.tests.test_filtering_common module

Test filtering backend.

class django_elasticsearch_dsl_drf.tests.test_filtering_common.TestFilteringCommon(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin, django_elasticsearch_dsl_drf.tests.data_mixins.BooksMixin

Test filtering common.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_default_filter_lookup()[source]

Test default filter lookup.

Example:

test_field_filter_contains()[source]

Test filter contains.

Example:

test_field_filter_endswith()[source]

Test filter endswith.

Example:

test_field_filter_exclude()[source]

Test filter exclude.

Example:

test_field_filter_exists_false()[source]

Test filter exists.

Example:

test_field_filter_exists_true()[source]

Test filter exists true.

Example:

test_field_filter_gt()[source]

Field filter gt.

Example:

Returns:
test_field_filter_gt_with_boost()[source]

Field filter gt with boost.

Example:

Returns:
test_field_filter_gte()[source]

Field filter gte.

Example:

Returns:
test_field_filter_in()[source]

Test filter in.

Example:

test_field_filter_isnull_false()[source]

Test filter isnull true.

Example:

test_field_filter_isnull_true()[source]

Test filter isnull true.

Example:

test_field_filter_lt()[source]

Field filter lt.

Example:

Returns:
test_field_filter_lt_with_boost()[source]

Field filter lt with boost.

Example:

Returns:
test_field_filter_lte()[source]

Field filter lte.

Example:

Returns:
test_field_filter_prefix()[source]

Test filter prefix.

Example:

test_field_filter_range()[source]

Field filter range.

Example:

test_field_filter_range_with_boost()[source]

Field filter range.

Example:

test_field_filter_term()[source]

Field filter term.

test_field_filter_term_explicit()[source]

Field filter term.

test_field_filter_terms_list()[source]

Test filter terms.

test_field_filter_terms_string()[source]

Test filter terms.

Example:

test_field_filter_wildcard()[source]

Test filter wildcard.

Example:

test_ids_empty_filter()[source]

Test ids filter with empty value. This should not fail.

Example:

test_ids_filter()[source]

Test ids filter.

Example:

test_nested_field_filter_term()[source]

Nested field filter term.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

test_various_complex_fields()[source]

Test various complex fields.

Returns:
django_elasticsearch_dsl_drf.tests.test_filtering_geo_spatial module

Test geo-spatial filtering backend.

class django_elasticsearch_dsl_drf.tests.test_filtering_geo_spatial.TestFilteringGeoSpatial(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test filtering geo-spatial.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_geo_bounding_box()[source]

Test field filter geo-bounding-box.

Returns:
test_field_filter_geo_bounding_box_fail_test()[source]

Test field filter geo-bounding-box (fail test).

Returns:
test_field_filter_geo_distance()[source]

Field filter geo-distance.

Example:

http://localhost:8000 /api/publisher/?location__geo_distance=1km__48.8549__2.3000
Returns:
test_field_filter_geo_distance_distance_type_arc()[source]

Field filter geo-distance.

Example:

http://localhost:8000 /api/publisher/?location__geo_distance=1km__48.8549__2.3000__arc
Returns:
test_field_filter_geo_distance_not_enough_args_fail()[source]

Field filter geo-distance. Fail test on not enough args.

Example:

http://localhost:8000 /api/publisher/?location__geo_distance=1km__48.8549
Returns:
test_field_filter_geo_polygon()[source]

Test field filter geo-polygon.

Returns:
test_field_filter_geo_polygon_fail_test()[source]

Test field filter geo-polygon (fail test).

Returns:
test_field_filter_geo_polygon_string_options()[source]

Test field filter geo-polygon.

Returns:
test_field_filter_geo_polygon_string_options_fail_test()[source]

Test field filter geo-polygon (fail test).

Returns:
django_elasticsearch_dsl_drf.tests.test_filtering_global_aggregations module

Test filtering post_filter backend.

class django_elasticsearch_dsl_drf.tests.test_filtering_global_aggregations.TestFilteringGlobalAggregations(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin, django_elasticsearch_dsl_drf.tests.data_mixins.BooksMixin

Test filtering with global aggregations.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_list_results_with_facets()[source]

Test list results with facets.

django_elasticsearch_dsl_drf.tests.test_filtering_nested module

Test nested filtering backend.

class django_elasticsearch_dsl_drf.tests.test_filtering_nested.TestFilteringNested(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test filtering nested.

base_url
pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_contains()[source]

Test filter contains.

Example:

test_field_filter_endswith()[source]

Test filter endswith.

Example:

test_field_filter_exclude()[source]

Test filter exclude.

Example:

test_field_filter_exists_false()[source]

Test filter exists.

Example:

test_field_filter_exists_true()[source]

Test filter exists true.

Example:

test_field_filter_in()[source]

Test filter in.

Example:

test_field_filter_prefix()[source]

Test filter prefix.

Example:

test_field_filter_range()[source]

Field filter range.

Example:

test_field_filter_range_with_boost()[source]

Field filter range.

Example:

test_field_filter_term()[source]

Field filter term.

test_field_filter_term_explicit()[source]

Field filter term.

test_field_filter_terms_list()[source]

Test filter terms.

test_field_filter_terms_string()[source]

Test filter terms.

Example:

test_field_filter_wildcard()[source]

Test filter wildcard.

Example:

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

django_elasticsearch_dsl_drf.tests.test_filtering_post_filter module

Test filtering post_filter backend.

class django_elasticsearch_dsl_drf.tests.test_filtering_post_filter.TestFilteringPostFilter(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin, django_elasticsearch_dsl_drf.tests.data_mixins.BooksMixin

Test filtering post_filter.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_contains()[source]

Test filter contains.

Example:

test_field_filter_endswith()[source]

Test filter endswith.

Example:

test_field_filter_exclude()[source]

Test filter exclude.

Example:

test_field_filter_exists_false()[source]

Test filter exists.

Example:

test_field_filter_exists_true()[source]

Test filter exists true.

Example:

test_field_filter_gt()[source]

Field filter gt.

Example:

Returns:
test_field_filter_gt_with_boost()[source]

Field filter gt with boost.

Example:

Returns:
test_field_filter_gte()[source]

Field filter gte.

Example:

Returns:
test_field_filter_in()[source]

Test filter in.

Example:

test_field_filter_isnull_false()[source]

Test filter isnull true.

Example:

test_field_filter_isnull_true()[source]

Test filter isnull true.

Example:

test_field_filter_lt()[source]

Field filter lt.

Example:

Returns:
test_field_filter_lt_with_boost()[source]

Field filter lt with boost.

Example:

Returns:
test_field_filter_lte()[source]

Field filter lte.

Example:

Returns:
test_field_filter_prefix()[source]

Test filter prefix.

Example:

test_field_filter_range()[source]

Field filter range.

Example:

test_field_filter_range_with_boost()[source]

Field filter range.

Example:

test_field_filter_term()[source]

Field filter term.

test_field_filter_term_explicit()[source]

Field filter term.

test_field_filter_terms_list()[source]

Test filter terms.

test_field_filter_terms_string()[source]

Test filter terms.

Example:

test_field_filter_wildcard()[source]

Test filter wildcard.

Example:

test_ids_filter()[source]

Test ids filter.

Example:

test_list_results_with_facets()[source]

Test list results with facets.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

test_various_complex_fields()[source]

Test various complex fields.

Returns:
django_elasticsearch_dsl_drf.tests.test_functional_suggesters module

Test functional suggestions backend.

class django_elasticsearch_dsl_drf.tests.test_functional_suggesters.TestFunctionalSuggesters(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test functional suggesters.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_suggesters_completion()[source]

Test suggesters completion.

test_suggesters_completion_no_args_provided()[source]

Test suggesters completion with no args provided.

django_elasticsearch_dsl_drf.tests.test_helpers module

Test helpers.

class django_elasticsearch_dsl_drf.tests.test_helpers.TestHelpers(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseTestCase

Test helpers.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_filter_by_field()[source]

Filter by field.

django_elasticsearch_dsl_drf.tests.test_highlight module

Test highlight backend.

class django_elasticsearch_dsl_drf.tests.test_highlight.TestHighlight(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test highlight.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_list_results_with_highlights()[source]

Test list results with facets.

django_elasticsearch_dsl_drf.tests.test_more_like_this module

Test more-like-this functionality.

class django_elasticsearch_dsl_drf.tests.test_more_like_this.TestMoreLikeThis(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test suggesters.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_more_like_this()[source]

Test more-like-this.

django_elasticsearch_dsl_drf.tests.test_ordering_common module

Test ordering backend.

class django_elasticsearch_dsl_drf.tests.test_ordering_common.TestOrdering(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test ordering.

static deep_get(dic, keys, default=None)[source]

Returns value at period separated keys in dictionary or default

From https://stackoverflow.com/a/46890853

Parameters:
  • dic (dict) – Dictionary to retrieve value from.
  • keys (str) – Period separated path of keys
  • default (str) – Default value to return if keys not found
Returns:

Value at keys or default

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_address_default_nested_order_by()[source]
test_address_default_order_by()[source]

Test if default ordering on addresses is correct (asc).

test_address_order_by_nested_field_continent_ascending()[source]

Order by field continent.country.name.raw ascending.

test_address_order_by_nested_field_continent_descending()[source]

Order by field continent.country.name.raw descending.

test_address_order_by_nested_field_country_ascending()[source]

Order by field continent.country.name.raw ascending.

test_address_order_by_nested_field_country_descending()[source]

Order by field continent.country.name.raw descending.

test_author_default_order_by()[source]

Author order by default.

test_author_order_by_field_id_ascending()[source]

Order by field name ascending.

test_author_order_by_field_id_descending()[source]

Order by field id descending.

test_author_order_by_field_name_ascending()[source]

Order by field name ascending.

test_author_order_by_field_name_descending()[source]

Order by field name descending.

test_book_default_order_by()[source]

Book order by default.

test_book_order_by_field_id_ascending()[source]

Order by field id ascending.

test_book_order_by_field_id_descending()[source]

Order by field id descending.

test_book_order_by_field_title_ascending()[source]

Order by field title ascending.

test_book_order_by_field_title_descending()[source]

Order by field title descending.

test_book_order_by_non_existent_field()[source]

Order by non-existent field.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

django_elasticsearch_dsl_drf.tests.test_ordering_geo_spatial module

Test geo-spatial ordering filter backend.

class django_elasticsearch_dsl_drf.tests.test_ordering_geo_spatial.TestOrderingGeoSpatial(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test ordering geo-spatial.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_geo_distance()[source]

Field filter geo_distance.

Example:

http://localhost:8000 /api/publisher/?ordering=location;48.85;2.30;km;plane
django_elasticsearch_dsl_drf.tests.test_pagination module

Test pagination.

class django_elasticsearch_dsl_drf.tests.test_pagination.TestPagination(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test pagination.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_pagination()[source]

Test pagination.

django_elasticsearch_dsl_drf.tests.test_pip_helpers module

Test pip_helpers.

class django_elasticsearch_dsl_drf.tests.test_pip_helpers.TestPipHelpers(methodName='runTest')[source]

Bases: unittest.case.TestCase

Test pip_helpers.

pytestmark = [Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Hook method for setting up class fixture before running tests in the class.

test_check_if_installed()[source]

Test check_if_installed.

Returns:
test_get_installed_packages()[source]

Test get_installed_packages.

Returns:
test_get_installed_packages_with_versions()[source]

Test get_installed_packages.

Returns:
django_elasticsearch_dsl_drf.tests.test_search_multi_match module

Test multi match search filter backend.

class django_elasticsearch_dsl_drf.tests.test_search_multi_match.TestMultiMatchSearch(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test multi match search.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

Search.

test_search_boost(url=None)[source]

Search boost.

Returns:
test_search_boost_selected_fields(url=None)[source]

Search boost.

Returns:
test_search_selected_fields(url=None)[source]

Search boost.

Returns:
django_elasticsearch_dsl_drf.tests.test_search_simple_query_string module

Test multi match search filter backend.

class django_elasticsearch_dsl_drf.tests.test_search_simple_query_string.TestSimpleQueryStringSearch(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test simple query string search.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

test_search_boost_selected_fields(url=None)[source]

Search boost.

Returns:
test_search_selected_fields(url=None)[source]

Search boost.

Returns:
test_search_with_quotes(url=None)[source]

Search with quotes.

test_search_with_quotes_alternative()[source]

Test search by field.

Parameters:url
Returns:
test_search_with_quotes_boost(url=None)[source]

Search boost.

Returns:
test_search_with_quotes_boost_alternative()[source]

Search boost.

Returns:
test_search_without_quotes(url=None)[source]

Test search without quotes. This does not work on Elasticsearch 6.x.

Parameters:url
Returns:
test_search_without_quotes_boost(url=None)[source]

Search boost without quotes. Does not work on Elasticsearch 6.x.

Returns:
django_elasticsearch_dsl_drf.tests.test_serializers module

Test serializers.

class django_elasticsearch_dsl_drf.tests.test_serializers.TestSerializers(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test serializers.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
test_serializer_document_equals_to_none()[source]

Test serializer no document specified.

test_serializer_fields_and_exclude()[source]

Test serializer fields and exclude.

test_serializer_meta_del_attr()[source]

Test serializer set attr.

test_serializer_meta_set_attr()[source]

Test serializer set attr.

test_serializer_no_document_specified()[source]

Test serializer no document specified.

django_elasticsearch_dsl_drf.tests.test_suggesters module

Test suggestions backend.

class django_elasticsearch_dsl_drf.tests.test_suggesters.TestContextSuggesters(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test context suggesters.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_suggesters_completion_context()[source]

Test suggesters completion context.

class django_elasticsearch_dsl_drf.tests.test_suggesters.TestSuggesters(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test suggesters.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_nested_fields_suggesters_completion()[source]

Test suggesters completion for nested fields.

test_suggesters_completion()[source]

Test suggesters completion.

test_suggesters_completion_no_args_provided()[source]

Test suggesters completion with no args provided.

test_suggesters_phrase()[source]

Test suggesters phrase.

test_suggesters_term()[source]

Test suggesters term.

class django_elasticsearch_dsl_drf.tests.test_suggesters.TestSuggestersEmptyIndex(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test suggesters on empty index.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_suggesters_on_empty_index()[source]

Test suggesters phrase.

django_elasticsearch_dsl_drf.tests.test_views module

Test views.

class django_elasticsearch_dsl_drf.tests.test_views.TestViews(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test views.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_detail_view()[source]

Test detail view.

test_detail_view_with_custom_lookup()[source]

Test detail view with a custom lookup field.

test_listing_view()[source]

Test listing view.

django_elasticsearch_dsl_drf.tests.test_wrappers module

Test wrappers.

class django_elasticsearch_dsl_drf.tests.test_wrappers.TestWrappers(methodName='runTest')[source]

Bases: unittest.case.TestCase

Test wrappers.

pytestmark = [Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Hook method for setting up class fixture before running tests in the class.

test_dict_to_obj()[source]

Test dict_to_obj.

Returns:
test_obj_to_dict()[source]

Test obj_to_dict.

Returns:
test_wrapper_as_json()[source]

Test :Wrapper:`as_json` property.

Module contents

Tests.

class django_elasticsearch_dsl_drf.tests.TestFacetedSearch(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test faceted search.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_list_results_with_facets()[source]

Test list results with facets.

class django_elasticsearch_dsl_drf.tests.TestFilteringCommon(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin, django_elasticsearch_dsl_drf.tests.data_mixins.BooksMixin

Test filtering common.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_default_filter_lookup()[source]

Test default filter lookup.

Example:

test_field_filter_contains()[source]

Test filter contains.

Example:

test_field_filter_endswith()[source]

Test filter endswith.

Example:

test_field_filter_exclude()[source]

Test filter exclude.

Example:

test_field_filter_exists_false()[source]

Test filter exists.

Example:

test_field_filter_exists_true()[source]

Test filter exists true.

Example:

test_field_filter_gt()[source]

Field filter gt.

Example:

Returns:
test_field_filter_gt_with_boost()[source]

Field filter gt with boost.

Example:

Returns:
test_field_filter_gte()[source]

Field filter gte.

Example:

Returns:
test_field_filter_in()[source]

Test filter in.

Example:

test_field_filter_isnull_false()[source]

Test filter isnull true.

Example:

test_field_filter_isnull_true()[source]

Test filter isnull true.

Example:

test_field_filter_lt()[source]

Field filter lt.

Example:

Returns:
test_field_filter_lt_with_boost()[source]

Field filter lt with boost.

Example:

Returns:
test_field_filter_lte()[source]

Field filter lte.

Example:

Returns:
test_field_filter_prefix()[source]

Test filter prefix.

Example:

test_field_filter_range()[source]

Field filter range.

Example:

test_field_filter_range_with_boost()[source]

Field filter range.

Example:

test_field_filter_term()[source]

Field filter term.

test_field_filter_term_explicit()[source]

Field filter term.

test_field_filter_terms_list()[source]

Test filter terms.

test_field_filter_terms_string()[source]

Test filter terms.

Example:

test_field_filter_wildcard()[source]

Test filter wildcard.

Example:

test_ids_empty_filter()[source]

Test ids filter with empty value. This should not fail.

Example:

test_ids_filter()[source]

Test ids filter.

Example:

test_nested_field_filter_term()[source]

Nested field filter term.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

test_various_complex_fields()[source]

Test various complex fields.

Returns:
class django_elasticsearch_dsl_drf.tests.TestFilteringGeoSpatial(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test filtering geo-spatial.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_geo_bounding_box()[source]

Test field filter geo-bounding-box.

Returns:
test_field_filter_geo_bounding_box_fail_test()[source]

Test field filter geo-bounding-box (fail test).

Returns:
test_field_filter_geo_distance()[source]

Field filter geo-distance.

Example:

http://localhost:8000 /api/publisher/?location__geo_distance=1km__48.8549__2.3000
Returns:
test_field_filter_geo_distance_distance_type_arc()[source]

Field filter geo-distance.

Example:

http://localhost:8000 /api/publisher/?location__geo_distance=1km__48.8549__2.3000__arc
Returns:
test_field_filter_geo_distance_not_enough_args_fail()[source]

Field filter geo-distance. Fail test on not enough args.

Example:

http://localhost:8000 /api/publisher/?location__geo_distance=1km__48.8549
Returns:
test_field_filter_geo_polygon()[source]

Test field filter geo-polygon.

Returns:
test_field_filter_geo_polygon_fail_test()[source]

Test field filter geo-polygon (fail test).

Returns:
test_field_filter_geo_polygon_string_options()[source]

Test field filter geo-polygon.

Returns:
test_field_filter_geo_polygon_string_options_fail_test()[source]

Test field filter geo-polygon (fail test).

Returns:
class django_elasticsearch_dsl_drf.tests.TestFilteringGlobalAggregations(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin, django_elasticsearch_dsl_drf.tests.data_mixins.BooksMixin

Test filtering with global aggregations.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_list_results_with_facets()[source]

Test list results with facets.

class django_elasticsearch_dsl_drf.tests.TestFilteringNested(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test filtering nested.

base_url
pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_contains()[source]

Test filter contains.

Example:

test_field_filter_endswith()[source]

Test filter endswith.

Example:

test_field_filter_exclude()[source]

Test filter exclude.

Example:

test_field_filter_exists_false()[source]

Test filter exists.

Example:

test_field_filter_exists_true()[source]

Test filter exists true.

Example:

test_field_filter_in()[source]

Test filter in.

Example:

test_field_filter_prefix()[source]

Test filter prefix.

Example:

test_field_filter_range()[source]

Field filter range.

Example:

test_field_filter_range_with_boost()[source]

Field filter range.

Example:

test_field_filter_term()[source]

Field filter term.

test_field_filter_term_explicit()[source]

Field filter term.

test_field_filter_terms_list()[source]

Test filter terms.

test_field_filter_terms_string()[source]

Test filter terms.

Example:

test_field_filter_wildcard()[source]

Test filter wildcard.

Example:

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

class django_elasticsearch_dsl_drf.tests.TestFilteringPostFilter(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin, django_elasticsearch_dsl_drf.tests.data_mixins.BooksMixin

Test filtering post_filter.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_contains()[source]

Test filter contains.

Example:

test_field_filter_endswith()[source]

Test filter endswith.

Example:

test_field_filter_exclude()[source]

Test filter exclude.

Example:

test_field_filter_exists_false()[source]

Test filter exists.

Example:

test_field_filter_exists_true()[source]

Test filter exists true.

Example:

test_field_filter_gt()[source]

Field filter gt.

Example:

Returns:
test_field_filter_gt_with_boost()[source]

Field filter gt with boost.

Example:

Returns:
test_field_filter_gte()[source]

Field filter gte.

Example:

Returns:
test_field_filter_in()[source]

Test filter in.

Example:

test_field_filter_isnull_false()[source]

Test filter isnull true.

Example:

test_field_filter_isnull_true()[source]

Test filter isnull true.

Example:

test_field_filter_lt()[source]

Field filter lt.

Example:

Returns:
test_field_filter_lt_with_boost()[source]

Field filter lt with boost.

Example:

Returns:
test_field_filter_lte()[source]

Field filter lte.

Example:

Returns:
test_field_filter_prefix()[source]

Test filter prefix.

Example:

test_field_filter_range()[source]

Field filter range.

Example:

test_field_filter_range_with_boost()[source]

Field filter range.

Example:

test_field_filter_term()[source]

Field filter term.

test_field_filter_term_explicit()[source]

Field filter term.

test_field_filter_terms_list()[source]

Test filter terms.

test_field_filter_terms_string()[source]

Test filter terms.

Example:

test_field_filter_wildcard()[source]

Test filter wildcard.

Example:

test_ids_filter()[source]

Test ids filter.

Example:

test_list_results_with_facets()[source]

Test list results with facets.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

test_various_complex_fields()[source]

Test various complex fields.

Returns:
class django_elasticsearch_dsl_drf.tests.TestFunctionalSuggesters(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test functional suggesters.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_suggesters_completion()[source]

Test suggesters completion.

test_suggesters_completion_no_args_provided()[source]

Test suggesters completion with no args provided.

class django_elasticsearch_dsl_drf.tests.TestHelpers(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseTestCase

Test helpers.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_filter_by_field()[source]

Filter by field.

class django_elasticsearch_dsl_drf.tests.TestHighlight(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test highlight.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_list_results_with_highlights()[source]

Test list results with facets.

class django_elasticsearch_dsl_drf.tests.TestMultiMatchSearch(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test multi match search.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

Search.

test_search_boost(url=None)[source]

Search boost.

Returns:
test_search_boost_selected_fields(url=None)[source]

Search boost.

Returns:
test_search_selected_fields(url=None)[source]

Search boost.

Returns:
class django_elasticsearch_dsl_drf.tests.TestSimpleQueryStringSearch(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test simple query string search.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

test_search_boost_selected_fields(url=None)[source]

Search boost.

Returns:
test_search_selected_fields(url=None)[source]

Search boost.

Returns:
test_search_with_quotes(url=None)[source]

Search with quotes.

test_search_with_quotes_alternative()[source]

Test search by field.

Parameters:url
Returns:
test_search_with_quotes_boost(url=None)[source]

Search boost.

Returns:
test_search_with_quotes_boost_alternative()[source]

Search boost.

Returns:
test_search_without_quotes(url=None)[source]

Test search without quotes. This does not work on Elasticsearch 6.x.

Parameters:url
Returns:
test_search_without_quotes_boost(url=None)[source]

Search boost without quotes. Does not work on Elasticsearch 6.x.

Returns:
class django_elasticsearch_dsl_drf.tests.TestOrdering(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test ordering.

static deep_get(dic, keys, default=None)[source]

Returns value at period separated keys in dictionary or default

From https://stackoverflow.com/a/46890853

Parameters:
  • dic (dict) – Dictionary to retrieve value from.
  • keys (str) – Period separated path of keys
  • default (str) – Default value to return if keys not found
Returns:

Value at keys or default

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_address_default_nested_order_by()[source]
test_address_default_order_by()[source]

Test if default ordering on addresses is correct (asc).

test_address_order_by_nested_field_continent_ascending()[source]

Order by field continent.country.name.raw ascending.

test_address_order_by_nested_field_continent_descending()[source]

Order by field continent.country.name.raw descending.

test_address_order_by_nested_field_country_ascending()[source]

Order by field continent.country.name.raw ascending.

test_address_order_by_nested_field_country_descending()[source]

Order by field continent.country.name.raw descending.

test_author_default_order_by()[source]

Author order by default.

test_author_order_by_field_id_ascending()[source]

Order by field name ascending.

test_author_order_by_field_id_descending()[source]

Order by field id descending.

test_author_order_by_field_name_ascending()[source]

Order by field name ascending.

test_author_order_by_field_name_descending()[source]

Order by field name descending.

test_book_default_order_by()[source]

Book order by default.

test_book_order_by_field_id_ascending()[source]

Order by field id ascending.

test_book_order_by_field_id_descending()[source]

Order by field id descending.

test_book_order_by_field_title_ascending()[source]

Order by field title ascending.

test_book_order_by_field_title_descending()[source]

Order by field title descending.

test_book_order_by_non_existent_field()[source]

Order by non-existent field.

test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

class django_elasticsearch_dsl_drf.tests.TestOrderingGeoSpatial(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test ordering geo-spatial.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up.

test_field_filter_geo_distance()[source]

Field filter geo_distance.

Example:

http://localhost:8000 /api/publisher/?ordering=location;48.85;2.30;km;plane
class django_elasticsearch_dsl_drf.tests.TestPagination(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test pagination.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_pagination()[source]

Test pagination.

class django_elasticsearch_dsl_drf.tests.TestPipHelpers(methodName='runTest')[source]

Bases: unittest.case.TestCase

Test pip_helpers.

pytestmark = [Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Hook method for setting up class fixture before running tests in the class.

test_check_if_installed()[source]

Test check_if_installed.

Returns:
test_get_installed_packages()[source]

Test get_installed_packages.

Returns:
test_get_installed_packages_with_versions()[source]

Test get_installed_packages.

Returns:
class django_elasticsearch_dsl_drf.tests.TestSearch(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test search.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUp()[source]

Hook method for setting up the test fixture before exercising it.

test_compound_search_boost_by_field()[source]
test_compound_search_by_field()[source]
test_compound_search_by_field_multi_terms()[source]
test_compound_search_by_nested_field()[source]
test_schema_field_not_required()[source]

Test schema fields always not required

test_schema_fields_with_filter_fields_list()[source]

Test schema field generator

test_search_boost(url=None, search_field='search')[source]

Search boost.

Returns:
test_search_boost_compound(search_field='search')[source]
test_search_by_field(url=None, search_field='search')[source]

Search by field.

test_search_by_field_multi_terms(url=None, search_field='search')[source]

Search by field, multiple terms.

test_search_by_nested_field(url=None)[source]

Search by field.

class django_elasticsearch_dsl_drf.tests.TestSerializers(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test serializers.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
test_serializer_document_equals_to_none()[source]

Test serializer no document specified.

test_serializer_fields_and_exclude()[source]

Test serializer fields and exclude.

test_serializer_meta_del_attr()[source]

Test serializer set attr.

test_serializer_meta_set_attr()[source]

Test serializer set attr.

test_serializer_no_document_specified()[source]

Test serializer no document specified.

class django_elasticsearch_dsl_drf.tests.TestSuggesters(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase, django_elasticsearch_dsl_drf.tests.data_mixins.AddressesMixin

Test suggesters.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_nested_fields_suggesters_completion()[source]

Test suggesters completion for nested fields.

test_suggesters_completion()[source]

Test suggesters completion.

test_suggesters_completion_no_args_provided()[source]

Test suggesters completion with no args provided.

test_suggesters_phrase()[source]

Test suggesters phrase.

test_suggesters_term()[source]

Test suggesters term.

class django_elasticsearch_dsl_drf.tests.TestViews(methodName='runTest')[source]

Bases: django_elasticsearch_dsl_drf.tests.base.BaseRestFrameworkTestCase

Test views.

pytestmark = [Mark(name='django_db', args=(), kwargs={}), Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Set up class.

test_detail_view()[source]

Test detail view.

test_detail_view_with_custom_lookup()[source]

Test detail view with a custom lookup field.

test_listing_view()[source]

Test listing view.

class django_elasticsearch_dsl_drf.tests.TestWrappers(methodName='runTest')[source]

Bases: unittest.case.TestCase

Test wrappers.

pytestmark = [Mark(name='django_db', args=(), kwargs={})]
classmethod setUpClass()[source]

Hook method for setting up class fixture before running tests in the class.

test_dict_to_obj()[source]

Test dict_to_obj.

Returns:
test_obj_to_dict()[source]

Test obj_to_dict.

Returns:
test_wrapper_as_json()[source]

Test :Wrapper:`as_json` property.

Submodules

django_elasticsearch_dsl_drf.analyzers module

Analyzers.

django_elasticsearch_dsl_drf.apps module

Apps.

class django_elasticsearch_dsl_drf.apps.Config(app_name, app_module)[source]

Bases: django.apps.config.AppConfig

Config.

label = 'django_elasticsearch_dsl_drf'
name = 'django_elasticsearch_dsl_drf'

django_elasticsearch_dsl_drf.compat module

Transitional compatibility module. Contains various field wrappers and helpers for painless (testing of) Elastic 2.x to Elastic 5.x transition. This module is not supposed to solve all transition issues for you. Better move to Elastic 5.x as soon as possible.

django_elasticsearch_dsl_drf.compat.get_elasticsearch_version(default=(2, 0, 0))[source]

Get Elasticsearch version.

Parameters:default (tuple) – Default value. Mainly added for building the docs when Elasticsearch is not running.
Returns:
Return type:list
django_elasticsearch_dsl_drf.compat.KeywordField(**kwargs)

Keyword field.

Parameters:kwargs
Returns:
django_elasticsearch_dsl_drf.compat.StringField(**kwargs)

String field.

Parameters:kwargs
Returns:

django_elasticsearch_dsl_drf.constants module

Constants module. Contains Elasticsearch constants, lookup constants, functional constants, suggesters, etc.

django_elasticsearch_dsl_drf.helpers module

Helpers.

django_elasticsearch_dsl_drf.helpers.get_document_for_model(model)[source]

Get document for model given.

Parameters:model (Subclass of django.db.models.Model.) – Model to get document index for.
Returns:Document index for the given model.
Return type:Subclass of django_elasticsearch_dsl.Document.
django_elasticsearch_dsl_drf.helpers.get_index_and_mapping_for_model(model)[source]

Get index and mapping for model.

Parameters:model (Subclass of django.db.models.Model.) – Django model for which to get index and mapping for.
Returns:Index and mapping values.
Return type:tuple.
django_elasticsearch_dsl_drf.helpers.more_like_this(obj, fields, max_query_terms=25, min_term_freq=2, min_doc_freq=5, max_doc_freq=0, query=None)[source]

More like this.

https://www.elastic.co/guide/en/elasticsearch/reference/current/ query-dsl-mlt-query.html

Parameters:
  • obj (Instance of django.db.models.Model (sub-classed) model.) – Django model instance for which similar objects shall be found.
  • fields (list) – Fields to search in.
  • max_query_terms (int) –
  • min_term_freq (int) –
  • min_doc_freq (int) –
  • max_doc_freq (int) –
  • query (elasticsearch_dsl.query.Q) – Q query
Returns:

List of objects.

Return type:

elasticsearch_dsl.search.Search

Example:

>>> from django_elasticsearch_dsl_drf.helpers import more_like_this
>>> from books.models import Book
>>> book = Book.objects.first()
>>> similar_books = more_like_this(
>>>     book,
>>>     ['title', 'description', 'summary']
>>> )
django_elasticsearch_dsl_drf.helpers.sort_by_list(unsorted_dict, sorted_keys)[source]

Sort an OrderedDict by list of sorted keys.

Parameters:
  • unsorted_dict (collections.OrderedDict) – Source dictionary.
  • sorted_keys (list) – Keys to sort on.
Returns:

Sorted dictionary.

Return type:

collections.OrderedDict

django_elasticsearch_dsl_drf.pagination module

Pagination.

class django_elasticsearch_dsl_drf.pagination.LimitOffsetPagination(*args, **kwargs)[source]

Bases: rest_framework.pagination.LimitOffsetPagination

A limit/offset pagination.

Example:

get_count(es_response)[source]

Determine an object count, supporting either querysets or regular lists.

get_facets(facets=None)[source]

Get facets.

Parameters:facets
Returns:
get_paginated_response(data)[source]

Get paginated response.

Parameters:data
Returns:
get_paginated_response_context(data)[source]

Get paginated response data.

Parameters:data
Returns:
paginate_queryset(queryset, request, view=None)[source]
class django_elasticsearch_dsl_drf.pagination.Page(object_list, number, paginator, facets)[source]

Bases: django.core.paginator.Page

Page for Elasticsearch.

class django_elasticsearch_dsl_drf.pagination.PageNumberPagination(*args, **kwargs)[source]

Bases: rest_framework.pagination.PageNumberPagination

Page number pagination.

A simple page number based style that supports page numbers as query parameters.

Example:

django_paginator_class

alias of Paginator

get_count(es_response)[source]
get_facets(page=None)[source]

Get facets.

Parameters:page
Returns:
get_paginated_response(data)[source]

Get paginated response.

Parameters:data
Returns:
get_paginated_response_context(data)[source]

Get paginated response data.

Parameters:data
Returns:
paginate_queryset(queryset, request, view=None)[source]

Paginate a queryset.

Paginate a queryset if required, either returning a page object, or None if pagination is not configured for this view.

Parameters:
  • queryset
  • request
  • view
Returns:

class django_elasticsearch_dsl_drf.pagination.Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)[source]

Bases: django.core.paginator.Paginator

Paginator for Elasticsearch.

page(number)[source]

Returns a Page object for the given 1-based page number.

Parameters:number
Returns:

django_elasticsearch_dsl_drf.pip_helpers module

Pip helpers module.

django_elasticsearch_dsl_drf.pip_helpers.check_if_installed(package, installed_packages=None)[source]

Check if package is installed.

Parameters:
  • package (str) –
  • installed_packages (iterable) –
Returns:

Return type:

bool

django_elasticsearch_dsl_drf.pip_helpers.get_installed_packages(with_versions=False)[source]

Get installed packages.

Parameters:with_versions (bool) – If set to True, returned with versions.
Returns:
Return type:list

django_elasticsearch_dsl_drf.serializers module

Serializers.

class django_elasticsearch_dsl_drf.serializers.DocumentSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.Serializer

A dynamic DocumentSerializer class.

create(validated_data)[source]

Create.

Do nothing.

Parameters:validated_data
Returns:
get_fields()[source]

Get the required fields for serializing the result.

update(instance, validated_data)[source]

Update.

Do nothing.

Parameters:
  • instance
  • validated_data
Returns:

class django_elasticsearch_dsl_drf.serializers.DocumentSerializerMeta[source]

Bases: rest_framework.serializers.SerializerMetaclass

Metaclass for the DocumentSerializer.

Ensures that all declared subclasses implemented a Meta.

class django_elasticsearch_dsl_drf.serializers.Meta[source]

Bases: type

Template for the DocumentSerializerMeta.Meta class.

exclude = ()
field_aliases = {}
field_options = {}
fields = ()
ignore_fields = ()
index_aliases = {}
index_classes = ()
search_fields = ()
serializers = ()

django_elasticsearch_dsl_drf.utils module

Utils.

class django_elasticsearch_dsl_drf.utils.DictionaryProxy(mapping)[source]

Bases: object

Dictionary proxy.

to_dict()[source]

To dict.

Returns:
class django_elasticsearch_dsl_drf.utils.EmptySearch(*args, **kwargs)[source]

Bases: object

Empty Search.

execute(*args, **kwargs)[source]
highlight(*args, **kwargs)[source]
sort(*args, **kwargs)[source]
to_dict(*args, **kwargs)[source]

django_elasticsearch_dsl_drf.versions module

Contains information about the current Elasticsearch version in use, including (LTE and GTE).

django_elasticsearch_dsl_drf.viewsets module

Base ViewSets.

class django_elasticsearch_dsl_drf.viewsets.BaseDocumentViewSet(*args, **kwargs)[source]

Bases: rest_framework.viewsets.ReadOnlyModelViewSet

Base document ViewSet.

document = None
document_uid_field = 'id'
get_object()[source]

Get object.

get_queryset()[source]

Get queryset.

ignore = []
pagination_class

alias of django_elasticsearch_dsl_drf.pagination.PageNumberPagination

class django_elasticsearch_dsl_drf.viewsets.DocumentViewSet(*args, **kwargs)[source]

Bases: django_elasticsearch_dsl_drf.viewsets.BaseDocumentViewSet, django_elasticsearch_dsl_drf.viewsets.SuggestMixin, django_elasticsearch_dsl_drf.viewsets.FunctionalSuggestMixin

DocumentViewSet with suggest and functional-suggest mix-ins.

class django_elasticsearch_dsl_drf.viewsets.FunctionalSuggestMixin[source]

Bases: object

Functional suggest mixin.

functional_suggest(request)[source]

Functional suggest functionality.

Parameters:request
Returns:
class django_elasticsearch_dsl_drf.viewsets.MoreLikeThisMixin[source]

Bases: object

More-like-this mixin.

more_like_this(request, pk=None, id=None)[source]

More-like-this functionality detail view.

Parameters:request
Returns:
class django_elasticsearch_dsl_drf.viewsets.SuggestMixin[source]

Bases: object

Suggest mixin.

suggest(request)[source]

Suggest functionality.

django_elasticsearch_dsl_drf.wrappers module

django_elasticsearch_dsl_drf.wrappers.dict_to_obj(mapping)[source]

dict to obj mapping.

Parameters:mapping (dict) –
Returns:
Return type:Wrapper
django_elasticsearch_dsl_drf.wrappers.obj_to_dict(obj)[source]

Wrapper to dict.

Parameters:obj (`obj`:Wrapper:) –
Returns:
Return type:dict
class django_elasticsearch_dsl_drf.wrappers.Wrapper[source]

Bases: object

Wrapper.

Example: >>> from django_elasticsearch_dsl_drf.wrappers import dict_to_obj >>> >>> mapping = { >>> ‘country’: { >>> ‘name’: ‘Netherlands’, >>> ‘province’: { >>> ‘name’: ‘North Holland’, >>> ‘city’: { >>> ‘name’: ‘Amsterdam’, >>> } >>> } >>> } >>> } >>> >>> wrapper = dict_to_obj(mapping) >>> wrapper.country.name >>> “Netherlands” >>> wrapper.country.province.name >>> “North Holland” >>> wrapper.country.province.city.name >>> “Amsterdam” >>> wrapper.as_dict >>> { >>> ‘country’: { >>> ‘name’: ‘Netherlands’, >>> ‘province’: { >>> ‘name’: ‘North Holland’, >>> ‘city’: { >>> ‘name’: ‘Amsterdam’, >>> } >>> } >>> } >>> } >>> str(wrapper) >>> “Netherlands”

as_dict

As dict.

Returns:
Return type:dict
as_json

As JSON.

Returns:
Return type:str

Module contents

Integrate Elasticsearch DSL with Django REST framework.