relevanssi_didyoumean()

relevanssi_didyoumean( string $query, string $pre, string $post, int $n = 5, boolean $echo = true )

Generates the Did you mean suggestions.

Source: /lib/didyoumean.php, /lib/common.php before 4.9.2 / 2.11.2.

Parameters

$query
(string) (required) The query string. If you don’t have it at hand, get_search_query( false ) is a good source.

$pre
(string) (required) This string is printed before the suggestion link.

$post
(string) (required) This string is printed after the suggestion link.

$n
(int) (optional) Maximum number of search results found for the suggestions to show up. If there are more results than this, the suggestions are not displayed.
Default value: 5

$echo
(boolean) (optional) If true, Relevanssi echoes the suggestion; otherwise, it is only returned.
Default value: true

Returns

(string|null) The HTML code for the suggestion element, or null if Relevanssi created no element.

Usage

This function is a wrapper for the actual logic, which depends on the version of Relevanssi used. Relevanssi Premium does the work in relevanssi_premium_didyoumean() and the free version does it in relevanssi_simple_didyoumean().

The typical way to use this is to add this to your theme search results template:

if ( function_exists( 'relevanssi_didyoumean' ) ) {
    relevanssi_didyoumean(
    	get_search_query( false ),
        '<p>Did you mean: ',
        '</p>',
        5
    );
}

This code will print out the suggestion if the Relevanssi search finds less than five results.

Pro tip: If you place this code inside the if ( have_posts() ) conditional in your template, it’ll only run when there’s a typo, but Relevanssi finds some posts. Most of the time that is not exactly what you want, so make sure you call the function when have_posts() returns false.

Free version

In the free version, the function relevanssi_simple_generate_suggestion() generates the suggestions and bases them on the logged searches. Relevanssi looks for searches that have found something and will use those as the material for suggestions. Thus, using the “Did you mean” feature requires search logs, and it takes some time before there are enough searches in the log so that the suggestions work correctly.

There’s caching involved: the query results are stored in a transient relevanssi_didyoumean_query for a month because it’s a bit slow query. This caching means that the suggestions are refreshed only once per month. If you’re debugging things, remove the transient to get new results.

Relevanssi matches the words based on the Levenshtein distance between the words.

Premium version

In Relevanssi Premium, the algorithm doesn’t use the search logs except as a backup. Premium looks for the words in your database, so whatever you use on your site is what it suggests. Relevanssi uses a spelling correction method that tries different removals, insertions and replacements with letters and sees what works.

The source material comes from your database. Getting the words can be a heavy query, so Relevanssi caches the results for a month. Relevanssi keeps the cache in the wp_options database in the option relevanssi_words. If you want to purge the cache, remove that option.

Relevanssi only includes words that appear at least twice in the database. On big sites, that’s too much, and it’s better to reduce the number of words included. You can adjust the minimum to 3 with this little snippet:

add_filter( 'relevanssi_get_words_having', function() { return 3; } );

This fix should be enough in most cases, but it may be helpful to lift the bar even higher on extensive sites.

Genesis

Here’s how you can use the “Did you mean” feature in Genesis themes. Add this to your site:

add_action( 'genesis_before_loop', 'genesis_add_didyoumean' );
function genesis_add_didyoumean() {
    if ( function_exists( 'relevanssi_didyoumean' ) ) {
        relevanssi_didyoumean( get_search_query( false ), '<p>Did you mean: ', '</p>', 5 );
    }
}	

Shortcode version

If you use a theme where modifying the search results template is difficult, it may be easier to use a shortcode version. Add this to your site:

add_shortcode( 'rlv_didyoumean', function() {
  $didyoumean = '';
  if ( function_exists( 'relevanssi_didyoumean' ) ) {
    $didyoumean = relevanssi_didyoumean(
      get_search_query( false ),
      '<p>Did you mean: ',
      '</p>',
      5,
      false
    );
  }
  return $didyoumean;
} );

Now you can add the shortcode [rlv_didyoumean] to your search results page, and the Did you mean text will appear there when necessary.

Troubleshooting Premium “Did you mean”

The “Did you mean” feature can sometimes fail to produce suggestions. First, check that the code is correctly in place in the template.

Because fetching all the words in the database can be a slow process, Relevanssi stores the word list in a cache. Relevanssi keeps the cache for a long time, so changes in the site don’t immediately reflect in the cache. If the cache is empty for some reason, Relevanssi can’t create any suggestions. The cache is in the relevanssi_words option in the wp_options database table, in case you want to inspect it.

You can reset the cache from the Debugging tab of Relevanssi settings. That’s an excellent first step. Relevanssi will regenerate it the next time it is needed when you reset the cache.

In some cases, Relevanssi has problems populating the cache. It usually points to one of two issues. Relevanssi updates the option as an AJAX action, and sometimes the action fails to run. It’s also possible the AJAX action runs, but the index is too big and populating the cache fails.

For the latter problem, the solution is to adjust the relevanssi_get_words_having filter hook to return a bigger number than 2. See above for sample code.

To help populate the cache in case the AJAX action fails, Relevanssi has a function that you can run to populate the cache. The function is relevanssi_update_words_option(), and you can call it like this:

if ( is_user_logged_in() ) {
  relevanssi_update_words_option();
}

Add this to your site, then visit your site. Relevanssi should now populate the cache and get the suggestions running. Remove this snippet after the suggestions start to work: you don’t want this function to run on every page load. If the AJAX action does not work, you want to run this function regularly, maybe once a week, biweekly or monthly, depending on how often you add new content to your site.

Automatic search for “Did you mean” corrections

If you want to make Relevanssi automatically search for corrected search terms if there are no results found for the original search term, you can do this using the relevanssi_fallback filter hook (this only works in Relevanssi Premium):

add_filter( 'relevanssi_fallback', 'rlv_didyoumean_fallback' );
function rlv_didyoumean_fallback( $args ) {
    global $relevanssi_dym_fallback;
    $query  = $args['args']['q'];
    $query  = htmlspecialchars_decode( $query );
    $tokens = relevanssi_tokenize( $query );

    $sc = new Relevanssi_SpellCorrector();

    $correct   = array();
    $new_query = $query;
    foreach ( array_keys( $tokens ) as $token ) {
        $token = trim( $token );
        $c     = $sc->correct( $token );
        if ( ! empty( $c ) && $c !== strval( $token ) ) {
            array_push( $correct, $c );
            $new_query = str_ireplace( $token, $c, $query );
        }
    }

    if ( $new_query !== $query ) {
        $relevanssi_dym_fallback = $new_query;
    
    	$args['args']['q'] = $new_query;
        remove_filter( 'relevanssi_fallback', 'rlv_didyoumean_fallback' );
        $return = relevanssi_search( $args['args'] );
        add_filter( 'relevanssi_fallback', 'rlv_didyoumean_fallback' );
        $args['return'] = $return;
    }
    return $args;
}

Suppose the search term doesn’t find any results. In that case, this function gets triggered, runs the spelling corrector for the search query and does a new search with the corrected query, hopefully returning valuable results.

If you add this code to your site, it will work automatically, but the change is invisible: your search results page will still show the original search term. That may be confusing. This function sets the global variable $relevanssi_dym_fallback and stores the corrected query in it.

You can use that global function on your search results template to figure out if the query has been corrected and then print out the updated search result:

<?php
	global $relevanssi_dym_fallback;
	if ( ! empty( $relevanssi_dym_fallback ) && $relevanssi_dym_fallback !== get_search_query() ) {
      	echo "<h2 class='page-title'>Actually searched for: $relevanssi_dym_fallback</h2>";
    }
?>

Filter hooks