Querying with Sphinx¶
This document presents the API of the Django-SphinxQL queryset, the high-level interface for interacting with Sphinx from Django.
SearchQuerySet¶
-
class
sphinxql.query.SearchQuerySet¶ SearchQuerySetis a subclass of DjangoQuerySetto allow text-based search with Sphinx; This search is constructed bysearch*methods and is lazily applied to the Django QuerySet before it hits Django’s database.Formally, a
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
Index.Meta.model.The API of
SearchQuerySetis the same asQuerySet, with the following additional methods:search(): for text searchingsearch_order_by(): for ordering the results of the searchsearch_filter(): for filtering the results of the search
If you don’t use any of these methods,
SearchQuerySetis equivalent to a DjangoQuerySetand can be directly replaced without any change.When you apply
search(),SearchQuerySetassumes you want to use Sphinx on it:-
search_mode¶ Defaults to
False. Defines whether Sphinx should be used by theSearchQuerySetprior to Django database hit. Automatically set toTruewhensearch()is used.
When
search_modeisTrue, the queryset performs a search in Sphinx database with the query built from thesearch*methods before interacting with Django database:- filtering done by
search()andsearch_filter()are applied before Django’s query, restricting the valididin the Django’s query. search_order_by()orders the results.
At most,
SearchQuerySetdoes 1 database hit in Sphinx, followed by the Django hit. Insearch_mode, theSearchQuerySethas an upper limit:-
max_search_count¶ 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
search_resultwith theIndexpopulated the values retrieved from Sphinx database.Below, the full API is explained in detail:
-
search(*extended_queries)¶ Adds a filter to text-search using Sphinx extended query syntax, defined by the strings
extended_queries. Subsequent calls of this method concatenate the differentextended_querywith a space (equivalent to anAND).This method automatically sets a search order according to relevance of the results given by the text search.
For instance:
>>> q = q.search('@text Hello world') >>> q = q.filter(number__gt=2)
- Searches for models with
Hello worldon the fieldtext - orders them by most relevant first and retrieves the first
max_search_countentries - 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):
- And:
' '(a space) - Or:
'|'('hello | world') - Not:
'-'or'!'(e.g.'hello -world') - Mandatory first term, optional second term:
'MAYBE'(e.g.'hello MAYBE world') - Phrase match:
'"<...>"'(e.g.'"hello world"') - Before match:
'<<'(e.g.'hello << world')
- Searches for models with
-
search_order_by(*expressions)¶ Adds
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 bynumberin decreasing order. Usesearch_order_by()to clear the ordering (default order is byid).There are two built-in columns,
'@id'and'@relevance', that are used to order by Djangoidand 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
idand:>>> 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
order_by.
-
search_filter(*conditions, **lookups)¶ Adds a filter to the search query, allowing you to restrict the search results of the search.
lookupsare like Django lookups forfilter. Just remember that the field name must be defined on thesphinxql.indexes.Index.conditionsshould be Django-SphinxQL expressions that return a boolean value (e.g.>=) and are used to produce more complex filters.You can use
lookupsandconditionsat the same time:>>> q = q.search_filter(number__in=(2,3), C('number1')**2 > 10)
The method joins all and each
lookupandconditionwithAND.Like in Django,
"id__"is reserved to indicate the object id (Sphinx shares the same ids as Django).
QuerySet¶
-
class
query.QuerySet¶ QuerySetis a Django-equivalentQuerySetto indexes. I.e. contrary toSearchQuerySet, 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:
-
search(*extended_queries)¶ Same as
SearchQuerySet.search().
-
filter(*conditions, **lookups)¶ Same as
SearchQuerySet.search_filter().
-
order_by(*expressions)¶ Same as
SearchQuerySet.search_order_by().
-
count()¶ Same as Django’s count.
-