Download as pdf or txt
Download as pdf or txt
You are on page 1of 1

Django ORM vs.

Elasticsearch DSL by @DjangoTricks

Django ORM Elasticsearch DSL


Query definition queryset = MyModel.objects.all() search = MyModelDocument.search()

Count queryset = queryset.count() search = search.count()

Iteration for item in queryset: for item in search:


print(item.title) print(item.title)

The generated queryset.query search.to_dict()


query
Filter by single queryset = queryset.filter(my_field__icontains=value) search = search.filter('match_phrase', my_field=value)
field containing a
value
Filter by single queryset = queryset.filter(my_field__exact=value) search = search.filter('match', my_field=value)
field exactly equal # For text fields use KeywordField() in the document:
to a value my_field = fields.KeywordField()

Filter with either from django.db import models from elasticsearch_dsl.query import Q
queryset = queryset.filter( search = search.query(
of the conditions models.Q(my_field=value) | Q('match', my_field=value) |
(OR) models.Q(my_field2=value2) Q('match', my_field2=value2)
) )

Filter with all of from django.db import models from elasticsearch_dsl.query import Q
queryset = queryset.filter( search = search.query(
the conditions models.Q(my_field=value) & Q('match', my_field=value) &
(AND) models.Q(my_field2=value2) Q('match', my_field2=value2)
) )

Filter by values queryset = queryset.filter( search = search.filter(


published_at__lte=datetime.now(), 'range',
less than or equal ) published_at={'lte': datetime.now()}
to certain value )

Filter by a value queryset = queryset.filter( from elasticsearch_dsl.query import Q


category__pk=category_id, search = search.filter(
in a nested field ) 'nested',
path='category',
query=Q('match', category__pk=category_id)
)

Filter by one of queryset = queryset.filter( from django.utils.six.moves import reduce


category__pk__in=category_ids, from elasticsearch_dsl.query import Q
many values in a ) search = search.query(
related model reduce(operator.ior, [
Q(
'nested',
path='category',
query=Q('match', category__pk=category_id),
)
for category_id in category_ids
])
)

Ordering queryset = queryset.order_by('-my_field', 'my_field2') search = search.sort('-my_field', 'my_field2')

Creating query import operator import operator


from django.utils.six.moves import reduce from django.utils.six.moves import reduce
dynamically from elasticsearch_dsl.query import Q
filters = []
if value1: queries = []
filters.append(models.Q( if value1:
my_field1=value1, queries.append(Q(
)) 'match',
if value2: my_field1=value1,
filters.append(models.Q( ))
my_field2=value2, if value2:
)) queries.append(Q(
queryset = queryset.filter( 'match',
reduce(operator.iand, filters) my_field2=value2,
) ))
search = search.query(
reduce(operator.iand, queries)
)

Pagination from django.core.paginator import ( from django.core.paginator import (


Paginator, Page, EmptyPage, PageNotAnInteger Paginator, Page, EmptyPage, PageNotAnInteger
) )
from django.utils.functional import LazyObject
paginator = Paginator(queryset, paginate_by)
page_number = request.GET.get('page') class SearchResults(LazyObject):
try: def __init__(self, search_object):
page = paginator.page(page_number) self._wrapped = search_object
except PageNotAnInteger:
page = paginator.page(1) def __len__(self):
except EmptyPage: return self._wrapped.count()
page = paginator.page(paginator.num_pages)
def __getitem__(self, index):
search_results = self._wrapped[index]
if isinstance(index, slice):
search_results = list(search_results)
return search_results

search_results = SearchResults(search)

paginator = Paginator(search_results, paginate_by)


page_number = request.GET.get('page')
try:
page = paginator.page(page_number)
except PageNotAnInteger:
page = paginator.page(1)
except EmptyPage:
page = paginator.page(paginator.num_pages)

Revision 05 March 2019 More details: http://bit.ly/2H7KK2e

You might also like