Posted on

Using the relevanssi_hits_filter hook

One of the most useful filter hooks in Relevanssi is the relevanssi_hits_filter, which lets you modify the array of posts Relevanssi finds. The filter passes an array, where index 0 gives the list of hits in the form of an array of post objects and index 1 has the search query as a string, in case you need that information for something.

For example, the WPML language filter in Relevanssi is done with this filter hook: it examines all the posts found and removes the ones that are not in the correct language. It can also be used to avoid complex taxonomy and meta queries; sometimes it’s faster to do a simple query and then filter out the unwanted results later. In some cases, it’s not even possible to formulate a query that would catch all the cases, but it will be straightforward to do that in the filter hook.

Here’s an example filter that will check the same meta field in different ways for different post types – that’s something that would be tricky to do with just meta_query:

add_filter( 'relevanssi_hits_filter', 'rlv_sample_filter', 10, 1 );
function rlv_sample_filter( $hits ) {
    $acceptable_fruit = array();
    foreach ( $hits[0] as $hit ) {
        if ( 'bananas' == $hit->post_type ) {
            // Accept only yellow bananas.
            if ( 'yellow' === get_post_meta( $hit->ID, 'color', true ) ) {
                $acceptable_fruit[] = $hit;
            }
        }
        if ( 'apples' == $hit->post_type ) {
            // Accept only red apples.
            if ( 'red' === get_post_meta( $hit->ID, 'color', true ) ) {
                $acceptable_fruit[] = $hit;
            }
        }
        if ( 'kiwis' == $hit->post_type ) {
            // Accept all kiwis.
            $acceptable_fruit[] = $hit;
        }
    }
    $hits[0] = $acceptable_fruit;
    return $hits;
}

The filter expects you to return an array containing the array of post objects in index 0. The search query is just for information, but if there are many filters on the relevanssi_hits_filter hook, some later function may expect it to be there. So, in order to avoid problems, it’s best to include the query string in the returned array, like this (assuming the function parameter array is called $hits):

$hits[0] = $your_processed_hits_array;
return $hits;

There are examples of using relevanssi_hits_filter for sorting posts in the user manual.

10 comments Using the relevanssi_hits_filter hook

  1. Do you have a suggestion for how to modify the filter to float results to the top by page type? I’ve built out all of the top pages on my site as tag pages and want those pages to appear at the top of search when there are any hits for those tags.

    1. Is there anything in the posts that you can use to recognize those tag pages? What does their post_type say? You can easily filter by any feature that’s present in the $post object.

  2. Hi Mikko!

    First of all thank you for the great plugin and your support. I have trouble in using relevanssi_hits_filter hook. It just doesn’t fire. I’d like to use it in functions.php. I also tried to use it in search.php but it doesn’t work there as well.

    Can you help to identify the cause of the problem?

    Thank you in advance!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.