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
¶ SearchQuerySet
is a subclass of DjangoQuerySet
to 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
SearchQuerySet
is 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
SearchQuerySet
is 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,
SearchQuerySet
is equivalent to a DjangoQuerySet
and can be directly replaced without any change.When you apply
search()
,SearchQuerySet
assumes you want to use Sphinx on it:-
search_mode
¶ Defaults to
False
. Defines whether Sphinx should be used by theSearchQuerySet
prior to Django database hit. Automatically set toTrue
whensearch()
is used.
When
search_mode
isTrue
, 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 validid
in the Django’s query. search_order_by()
orders the results.
At most,
SearchQuerySet
does 1 database hit in Sphinx, followed by the Django hit. Insearch_mode
, theSearchQuerySet
has 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_result
with theIndex
populated 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_query
with 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 world
on the fieldtext
- orders them by most relevant first and retrieves the first
max_search_count
entries - 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 BY
clauses 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 bynumber
in 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 Djangoid
and 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
id
and:>>> 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.
lookups
are like Django lookups forfilter
. Just remember that the field name must be defined on thesphinxql.indexes.Index
.conditions
should be Django-SphinxQL expressions that return a boolean value (e.g.>=
) and are used to produce more complex filters.You can use
lookups
andconditions
at the same time:>>> q = q.search_filter(number__in=(2,3), C('number1')**2 > 10)
The method joins all and each
lookup
andcondition
withAND
.Like in Django,
"id__"
is reserved to indicate the object id (Sphinx shares the same ids as Django).
QuerySet¶
-
class
query.
QuerySet
¶ QuerySet
is a Django-equivalentQuerySet
to 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.
-