.. _ref-searchquery-api: =================== ``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. .. 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`` ~~~~~~~~~~~~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~~ .. method:: SearchQuery.build_query(self) Interprets the collected query metadata and builds the final query to be sent to the backend. ``build_params`` ~~~~~~~~~~~~~~~~ .. method:: SearchQuery.build_params(self, spelling_query=None) Generates a list of params to use when searching. ``clean`` ~~~~~~~~~ .. method:: 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`` ~~~~~~~ .. method:: 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`` ~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~ .. method:: SearchQuery.run_raw(self, **kwargs) Executes a raw query. Returns a list of search results. ``get_count`` ~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~~~~~ .. method:: SearchQuery.boost_fragment(self, boost_word, boost_value) Generates query fragment for boosting a single word/value pair. ``matching_all_fragment`` ~~~~~~~~~~~~~~~~~~~~~~~~~ .. method:: SearchQuery.matching_all_fragment(self) Generates the query that matches all documents. ``add_filter`` ~~~~~~~~~~~~~~ .. method:: SearchQuery.add_filter(self, expression, value, use_not=False, use_or=False) Narrows the search by requiring certain conditions. ``add_order_by`` ~~~~~~~~~~~~~~~~ .. method:: SearchQuery.add_order_by(self, field) Orders the search result by a field. ``clear_order_by`` ~~~~~~~~~~~~~~~~~~ .. method:: SearchQuery.clear_order_by(self) Clears out all ordering that has been already added, reverting the query to relevancy. ``add_model`` ~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~ .. method:: SearchQuery.set_limits(self, low=None, high=None) Restricts the query by altering either the start, end or both offsets. ``clear_limits`` ~~~~~~~~~~~~~~~~ .. method:: SearchQuery.clear_limits(self) Clears any existing limits. ``add_boost`` ~~~~~~~~~~~~~ .. method:: SearchQuery.add_boost(self, term, boost_value) Adds a boosted term and the amount to boost it to the query. ``raw_search`` ~~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~~~~~ .. method:: SearchQuery.more_like_this(self, model_instance) Allows backends with support for "More Like This" to return results similar to the provided instance. ``add_highlight`` ~~~~~~~~~~~~~~~~~ .. method:: SearchQuery.add_highlight(self) Adds highlighting to the search results. ``add_field_facet`` ~~~~~~~~~~~~~~~~~~~ .. method:: SearchQuery.add_field_facet(self, field) Adds a regular facet on a field. ``add_date_facet`` ~~~~~~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~~~~~~ .. method:: SearchQuery.add_query_facet(self, field, query) Adds a query facet on a field. ``add_narrow_query`` ~~~~~~~~~~~~~~~~~~~~ .. method:: 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`` ~~~~~~~~~~~~~~~~~~~~ .. method:: 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.