SearchQuery API

class SearchQuery(using=DEFAULT_ALIAS)

The SearchQuery class acts as an intermediary between SearchQuerySet’s abstraction and SearchBackend’s actual search. Given the metadata provided by SearchQuerySet, SearchQuery builds 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. You can either hook it up in a BaseEngine subclass or 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.

Warning

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.

Example:

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:

build_query_fragment

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.

build_query

SearchQuery.build_query(self)

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

build_params

SearchQuery.build_params(self, spelling_query=None)

Generates a list of params to use when searching.

clean

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

SearchQuery.run(self, spelling_query=None, **kwargs)

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

Optionally passes along an alternate query for spelling suggestions.

Optionally passes along more kwargs for controlling the search query.

run_mlt

SearchQuery.run_mlt(self, **kwargs)

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

run_raw

SearchQuery.run_raw(self, **kwargs)

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

get_count

SearchQuery.get_count(self)

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.

get_results

SearchQuery.get_results(self, **kwargs)

Returns the results received from the backend.

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

get_facet_counts

SearchQuery.get_facet_counts(self)

Returns the results received from the backend.

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

boost_fragment

SearchQuery.boost_fragment(self, boost_word, boost_value)

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

matching_all_fragment

SearchQuery.matching_all_fragment(self)

Generates the query that matches all documents.

add_filter

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

Narrows the search by requiring certain conditions.

add_order_by

SearchQuery.add_order_by(self, field)

Orders the search result by a field.

clear_order_by

SearchQuery.clear_order_by(self)

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

add_model

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.

set_limits

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

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

clear_limits

SearchQuery.clear_limits(self)

Clears any existing limits.

add_boost

SearchQuery.add_boost(self, term, boost_value)

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

more_like_this

SearchQuery.more_like_this(self, model_instance)

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

add_stats_query

SearchQuery.add_stats_query(self, stats_field, stats_facets)

Adds stats and stats_facets queries for the Solr backend.

add_highlight

SearchQuery.add_highlight(self)

Adds highlighting to the search results.

add_within

SearchQuery.add_within(self, field, point_1, point_2):

Adds bounding box parameters to search query.

add_dwithin

SearchQuery.add_dwithin(self, field, point, distance):

Adds radius-based parameters to search query.

add_distance

SearchQuery.add_distance(self, field, point):

Denotes that results should include distance measurements from the point passed in.

add_field_facet

SearchQuery.add_field_facet(self, field, **options)

Adds a regular facet on a field.

add_date_facet

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

Adds a date-based facet on a field.

add_query_facet

SearchQuery.add_query_facet(self, field, query)

Adds a query facet on a field.

add_narrow_query

SearchQuery.add_narrow_query(self, query)

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

Generally used in conjunction with faceting.

set_result_class

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.

using

SearchQuery.using(self, using=None)

Allows for overriding which connection should be used. This disables the use of routers when performing the query.

If None is provided, it has no effect on what backend is used.