Querying with Sphinx¶
This document presents the API of the Django-SphinxQL queryset, the high-level interface for interacting with Sphinx from Django.
SearchQuerySetis a subclass of Django
QuerySetto allow text-based search with Sphinx; This search is constructed by
search*methods and is lazily applied to the Django QuerySet before it hits Django’s database.
SearchQuerySetis initialized with one parameter, the index it is bound to:
>>> q = SearchQuerySet(index, query=None, using=None)
that initializes Django’s queryset from the
The API of
SearchQuerySetis the same as
QuerySet, with the following additional methods:
search(): for text searching
search_order_by(): for ordering the results of the search
search_filter(): for filtering the results of the search
If you don’t use any of these methods,
SearchQuerySetis equivalent to a Django
QuerySetand can be directly replaced without any change.
When you apply
SearchQuerySetassumes you want to use Sphinx on it:
True, the queryset performs a search in Sphinx database with the query built from the
search*methods before interacting with Django database:
- filtering done by
search_filter()are applied before Django’s query, restricting the valid
idin the Django’s query.
search_order_by()orders the results.
SearchQuerySetdoes 1 database hit in Sphinx, followed by the Django hit. In
SearchQuerySethas an upper limit:
A class attribute defining the maximum number of entries returned by the Sphinx hit. Currently hardcoded to 1000.
Notice that this implies that any search-based query has always at most count 1000 (can be less if Django filters some).
If Sphinx is used, model objects are annotated with an attribute
Indexpopulated the values retrieved from Sphinx database.
Below, the full API is explained in detail:
Adds a filter to text-search using Sphinx extended query syntax, defined by the strings
extended_queries. Subsequent calls of this method concatenate the different
extended_querywith a space (equivalent to an
This method automatically sets a search order according to relevance of the results given by the text search.
>>> q = q.search('@text Hello world') >>> q = q.filter(number__gt=2)
- Searches for models with
Hello worldon the field
- orders them by most relevant first and retrieves the first
- filters the remaining entries with the Django query.
Notice that this method is orderless in the chain: Sphinx is always applied before the Django query.
search()supports arbitrary arguments to automatically restrict the search; the following are equivalent:
>>> q.search('@text Hello world @summary "my search"') >>> q.search('@text Hello world', '@summary "my search"')
For convenience, here is a list of some operators (full list here):
' '(a space)
'hello | world')
- Mandatory first term, optional second term:
'hello MAYBE world')
- Phrase match:
- Before match:
'hello << world')
- Searches for models with
ORDER BYclauses to Sphinx query. For example:
>>> q = q.search(a).search_order_by('-number')
will order first by the search relevance (
search()added it) and then by
numberin decreasing order. Use
search_order_by()to clear the ordering (default order is by
There are two built-in columns,
'@relevance', that are used to order by Django
idand by relevance of the results, respectively.
Notice that search ordering is applied before Django’s query is performed. Yet, the final result (after Django query) is ordered according to Django ordering unless you didn’t set any ordering to Django’s query. For example:
>>> q = q.order_by('id').search(a)
orders the final results by
>>> q = q.order_by('id').search(a).order_by()
orders the results by search relevance (because
order_by()cleared Django’s ordering).
In other words, the results are ordered by search ordering unless there is an explicit call of
Adds a filter to the search query, allowing you to restrict the search results of the search.
lookupsare like Django lookups for
filter. Just remember that the field name must be defined on the
conditionsshould be Django-SphinxQL expressions that return a boolean value (e.g.
>=) and are used to produce more complex filters.
You can use
conditionsat the same time:
>>> q = q.search_filter(number__in=(2,3), C('number1')**2 > 10)
The method joins all and each
Like in Django,
"id__"is reserved to indicate the object id (Sphinx shares the same ids as Django).
QuerySetis a Django-equivalent
QuerySetto indexes. I.e. contrary to
SearchQuerySet, this QuerySet only interacts with the Sphinx database and returns instances of the Index. This can be useful when you need to present results of a search that don’t need any extra data from Django.
The interface of this QuerySet is equivalent to Django QuerySet: it is lazy and allows chaining. However, the current implemented methods are limited:
Same as Django’s count.