SearchQuery API

class SearchQuery(backend=None)

The SearchQuery class acts as an intermediary between SearchQuerySet‘s abstraction and SearchBackend‘s actual search. Given the metadata provided by SearchQuerySet, SearchQuery build the actual query and interacts with the SearchBackend on SearchQuerySet‘s behalf.

This class must be at least partially implemented on a per-backend basis, as portions are highly specific to the backend. It usually is bundled with the accompanying SearchBackend.

Most people will NOT have to use this class directly. SearchQuerySet handles all interactions with SearchQuery objects and provides a nicer interface to work with.

Should you need advanced/custom behavior, you can supply your version of SearchQuery that overrides/extends the class in the manner you see fit. SearchQuerySet objects take a kwarg parameter query where you can pass in your class.

SQ Objects

For expressing more complex queries, especially involving AND/OR/NOT in different combinations, you should use SQ objects. Like django.db.models.Q objects, SQ objects can be passed to SearchQuerySet.filter and use the familiar unary operators (&, | and ~) to generate complex parts of the query.


Any data you pass to SQ objects is passed along unescaped. If you don’t trust the data you’re passing along, you should use the clean method on your SearchQuery to sanitize the data.


from haystack.query import SQ

# We want "title: Foo AND (tags:bar OR tags:moof)"
sqs = SearchQuerySet().filter(title='Foo').filter(SQ(tags='bar') | SQ(tags='moof'))

# To clean user-provided data:
sqs = SearchQuerySet()
clean_query = sqs.query.clean(user_query)
sqs = sqs.filter(SQ(title=clean_query) | SQ(tags=clean_query))

Internally, the SearchQuery object maintains a tree of SQ objects. Each SQ object supports what field it looks up against, what kind of lookup (i.e. the __ filters), what value it’s looking for, if it’s a AND/OR/NOT and tracks any children it may have. The SearchQuery.build_query method starts with the root of the tree, building part of the final query at each node until the full final query is ready for the SearchBackend.

Backend-Specific Methods

When implementing a new backend, the following methods will need to be created:


SearchQuery.build_query_fragment(self, field, filter_type, value)

Generates a query fragment from a field, filter type and a value.

Must be implemented in backends as this will be highly backend specific.

Inheritable Methods

The following methods have a complete implementation in the base class and can largely be used unchanged.



Interprets the collected query metadata and builds the final query to be sent to the backend.


SearchQuery.build_params(self, spelling_query=None)

Generates a list of params to use when searching.


SearchQuery.clean(self, query_fragment)

Provides a mechanism for sanitizing user input before presenting the value to the backend.

A basic (override-able) implementation is provided.

run, spelling_query=None)

Builds and executes the query. Returns a list of search results.

Optionally passes along an alternate query for spelling suggestions.



Executes the More Like This. Returns a list of search results similar to the provided document (and optionally query).



Executes a raw query. Returns a list of search results.



Returns the number of results the backend found for the query.

If the query has not been run, this will execute the query and store the results.



Returns the results received from the backend.

If the query has not been run, this will execute the query and store the results.



Returns the results received from the backend.

If the query has not been run, this will execute the query and store the results.


SearchQuery.boost_fragment(self, boost_word, boost_value)

Generates query fragment for boosting a single word/value pair.



Generates the query that matches all documents.


SearchQuery.add_filter(self, expression, value, use_not=False, use_or=False)

Narrows the search by requiring certain conditions.


SearchQuery.add_order_by(self, field)

Orders the search result by a field.



Clears out all ordering that has been already added, reverting the query to relevancy.


SearchQuery.add_model(self, model)

Restricts the query requiring matches in the given model.

This builds upon previous additions, so you can limit to multiple models by chaining this method several times.


SearchQuery.set_limits(self, low=None, high=None)

Restricts the query by altering either the start, end or both offsets.



Clears any existing limits.


SearchQuery.add_boost(self, term, boost_value)

Adds a boosted term and the amount to boost it to the query.


SearchQuery.more_like_this(self, model_instance)

Allows backends with support for “More Like This” to return results similar to the provided instance.



Adds highlighting to the search results.


SearchQuery.add_field_facet(self, field)

Adds a regular facet on a field.


SearchQuery.add_date_facet(self, field, start_date, end_date, gap_by, gap_amount)

Adds a date-based facet on a field.


SearchQuery.add_query_facet(self, field, query)

Adds a query facet on a field.


SearchQuery.add_narrow_query(self, query)

Narrows a search to a subset of all documents per the query.

Generally used in conjunction with faceting.


SearchQuery.set_result_class(self, klass)

Sets the result class to use for results.

Overrides any previous usages. If None is provided, Haystack will revert back to the default SearchResult object.