Skip to main contentSkip to footer

Complex queries

Find everything you need to know about complex queries

Most search queries are straightforward: the user enters a word or two and gets results. This kind of searching is easy to do and requires hardly any configuration with Relevanssi. But what if you need something more complicated?

Complex Queries Within the Search Form

These are things any user can do directly from the search form:

Phrase Matching: If you put multiple search terms in quotes, they become a phrase. Searching for "rosa parks" will only find posts that have this specific phrase in them. Relevanssi looks for phrases in post titles, post content, custom fields, and taxonomy terms.

If you include multiple phrases in the search query, their relationship depends on the default search operator. If Relevanssi settings use the OR search as default, Relevanssi returns any posts with at least one of the phrases. If the AND search is the default, all phrases must appear in the document.

Note: If the post content has HTML tags included, that will prevent the phrase matching from working. If your content reads Rosa <em>Parks</em>, a phrase search for "rosa parks" will not find this. The phrase must be the same, excluding differences in case.

Search Operators: (Premium only) Relevanssi Premium includes search operators which you can use to explicitly control the search behavior.

  • The + operator makes the word it’s attached to mandatory. In an OR search, searching for foo bar will include all posts that have one of these words. Searching for foo +bar requires all posts returned to include the word “bar”, and they may also include “foo”. This operator has no effect in an AND search.
  • The - operator excludes a word from the results. Searching for foo -bar returns all posts that have the word “foo”, but not the word “bar”. This works both in OR and AND searches.
  • The ? operator matches a single letter inside a word. Searching for w?rd would match “word” and “ward”, but not “weird”.
  • The * operator matches any number of letters (including zero) inside a word. Searching for w*rd matches “wrd”, “word”, “ward”, “weird”, and so on.

The wildcard operators are not on by default. Read more about them and how to enable wildcard matching from Wildcard matching.

Adding Query Parameters to the Search Form

The next step is to add extra properties to the search form in the form of query parameters. One straightforward way to do this is using the search form shortcode.

These query parameters are useful for filtering search results to restrict them somehow. This way, you can create a search form that only searches a part of your site, not everything. For filtering that users can’t control, you can use input fields with the type “hidden”.

Important: Hidden inputs add the query parameters to the search results page URL. If there’s a post type restriction, the user can simply remove it by deleting the parameter from the URL. For tamper-proof methods, use filter hooks (like relevanssi_modify_wp_query).

You can also add extra fields that the user can manipulate, like taxonomy dropdowns. The search form shortcode can be used to add these, but you can also build the search form from HTML and PHP to get the exact layout you want.

A full list of properties can be found in the WP_Query documentation. Some common options include:

  • Post type restrictions (post_type)
  • Category ID (cat) or name (category_name)
  • Tag ID (tag)
  • Author ID (author) or name (author_name)
  • Sorting (order, orderby)
  • Dates (year, monthnum, day, by_date)
  • Search operator, AND or OR (operator) (Premium only)

Using plugins to build more complex search forms is popular. FacetWP and Search & Filter Pro are the most common tools for this, and both work seamlessly with Relevanssi (with some caveats).

Working with Filters and PHP

For more complicated work, you can construct queries in code. There are two primary methods of constructing queries this way.

1. Replacing the main query
If you want to modify the main search results query, use filters. Sometimes people do this the wrong way by running a new WP_Query on the search results page. That’s wasteful. If you want to override the default query, modify the parameters for the existing main query instead. The Relevanssi-specific method is the relevanssi_modify_wp_query filter hook, and the general WordPress way is the pre_get_posts action hook.

add_filter( 'relevanssi_modify_wp_query', 'rlv_modify_query' );
function rlv_modify_query( $query ) {
  $query->set(
    'tax_query',
    array(
      array(
        'taxonomy' => 'genre',
        'terms'    => array( 'poetry', 'nonfiction' ),
        'field'    => 'slug',
      ),
    ),
  );
  return $query;
}

2. Running a new query
If you do need to run a new query (for example, outside the standard search results template), the best way to make Relevanssi take over is to set the relevanssi parameter to true. Relevanssi will handle these queries with no adverse effects, even if the plugin is temporarily deactivated.

$args = array(
  's'              => 'foo bar baz',
  'post_type'      => 'publish',
  'posts_per_page' => 20,
  'relevanssi'     => true,
);
$query = new WP_Query( $args );
// Now $query->posts has Relevanssi results.

These methods grant you access to very powerful filtering capabilities. The most notable are using taxonomy queries with the tax_query parameter, creating complex custom field queries with meta_query, and using date ranges with date_query. See the WP_Query Codex documentation for deep instructions.

There are some limitations to the tax_query arrays Relevanssi understands, but in most cases, even complex queries work perfectly if they are constructed with proper nested arrays. You can combine multiple taxonomies using Boolean logic. Here is an example of fetching posts in the “quotes” category OR posts that both have the “quote” post format AND are in the “wisdom” category:

$args = array(
  's'          => 'carrot',
  'post_type'  => 'post',
  'tax_query'  => array(
    'relation' => 'OR',
    array(
      'taxonomy' => 'category',
      'field'    => 'slug',
      'terms'    => array( 'quotes' ),
    ),
    array(
      'relation' => 'AND',
      array(
        'taxonomy' => 'post_format',
        'field'    => 'slug',
        'terms'    => array( 'post-format-quote' ),
      ),
      array(
        'taxonomy' => 'category',
        'field'    => 'slug',
        'terms'    => array( 'wisdom' ),
      ),
    ),
  ),
  'relevanssi' => true,
);
$query = new WP_Query( $args );
// $query->posts now has Relevanssi-generated wisdom on carrots.
Caution on Meta Queries: The same logic applies to meta queries; you can create incredibly complicated constructions. However, meta queries are usually the slowest operations in the WP_Query world. A complex meta query can be prohibitively slow to run. In advanced cases, it is often much faster to fetch all the relevant posts first and then use a relevanssi_hits_filter function to weed out the unwanted results.