# `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.

### `raw_search`

SearchQuery.raw_search(self, query_string, **kwargs)

Runs a raw query (no parsing) against the backend.

This method causes the `SearchQuery` to ignore the standard query-generating facilities, running only what was provided instead.

Note that any kwargs passed along will override anything provided to the rest of the `SearchQuerySet`.

### `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.