debian-django-haystack/docs/searchquery_api.rst

337 lines
8.7 KiB
ReStructuredText

.. _ref-searchquery-api:
===================
``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``
~~~~~~~~~~~~~~~~~~~~~~~~
.. 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_stats_query``
~~~~~~~~~~~~~~~~~~~
.. method:: SearchQuery.add_stats_query(self,stats_field,stats_facets)
Adds stats and stats_facets queries for the Solr backend.
``add_highlight``
~~~~~~~~~~~~~~~~~
.. method:: SearchQuery.add_highlight(self)
Adds highlighting to the search results.
``add_within``
~~~~~~~~~~~~~~
.. method:: SearchQuery.add_within(self, field, point_1, point_2):
Adds bounding box parameters to search query.
``add_dwithin``
~~~~~~~~~~~~~~~
.. method:: SearchQuery.add_dwithin(self, field, point, distance):
Adds radius-based parameters to search query.
``add_distance``
~~~~~~~~~~~~~~~~
.. method:: SearchQuery.add_distance(self, field, point):
Denotes that results should include distance measurements from the
point passed in.
``add_field_facet``
~~~~~~~~~~~~~~~~~~~
.. method:: SearchQuery.add_field_facet(self, field, **options)
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.
``using``
~~~~~~~~~
.. method:: 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.