Sort Wordpress Search by Relevance Sort Wordpress Search by Relevance wordpress wordpress

Sort Wordpress Search by Relevance


I think you can use Relevanssi without any problem but need to use a filter hook, check relevanssi_modify_wp_query for more details, check following code

function func_reli($qry){    $qry->set( 'post_type', array( 'post', 'page', 'restaurant', 'products' ) );    if ($_GET['myorder'] == 'price') {        $qry->set('orderby', 'meta_value_num');        $qry->set('meta_key', 'price');        $qry->set('order', 'ASC');    }    else {        $qry->set('orderby', 'date');        $qry->set('order', 'DESC'); // <-- set (in your code 'add' is used)    }    return $qry; // <-- must return, in your code you didn't}add_filter('relevanssi_modify_wp_query', 'func_reli');

I've tested this code and just works fine. In this example I've used 'restaurant' and 'products' custom post types and search works really fine, just the relevant results. You can also use if php 5.3+ is installed

add_filter('relevanssi_modify_wp_query', function($qry){    // Same code});

Also, if you use Relevanssi plugin, you can use it's setup page to set post_type instead of using this ($qry->set( 'post_type', array(...) )) in your functions.php file.

Scree shot given below

enter image description here


Ok so I ended up using Relevanssi after all. But with quite a few modifications.

First of all, filtering on taxonomies was quite easy as this is built into Relevanssi, all I needed to do was change the names of my <select> elements to the taxonomy names + change the values to the slugs:

<select name="custom_taxonomy">    <option value="some-term">Some term</option>    ...</select>

Second, to allow sorting by a custom field, I had to use the relevanssi_hits_filter filter. Unlike pre_get_posts or relevanssi_modify_wp_query (which Sheikh Heera kindly suggested), this filter gets passed the array of posts and not a WP_Query object. When I tried to use the WP_Query object the order simply refused to change. Here's basically how to do your own sort with relevanssi_hits_filter:

<?phpadd_filter('relevanssi_hits_filter', 'h5b_hits_filter');function h5b_hits_filter ($hits) {    global $wp_query;    if (isset($wp_query->query_vars['orderby']) and $wp_query->query_vars['orderby'] == 'price') {        if (count($hits[0])) {            usort($hits[0], 'h5b_sort_by_price');        }    }    return $hits;}function h5b_sort_by_price ($a, $b) {    $priceKey   = 'price';    $aPrice     = get_post_meta($a->ID, $priceKey, true);    $bPrice     = get_post_meta($b->ID, $priceKey, true);    $aPrice     = $aPrice ? $aPrice : 10000000;    $bPrice     = $bPrice ? $bPrice : 10000000;    if ($aPrice == $bPrice) {        return 0;    }    return ($aPrice < $bPrice) ? -1 : 1;}

This also helped with a previous problem I had in that posts that lacked the "price" key didn't show up in searches. Now they do, and the reason I give them a price of "10000000" is so that they show up after the ones that do have a price.

Finally, I also needed empty searches to work. According to the Relevanssi dev this is only supported in the Premium version, but I think I managed to work around it. First I forced WP to display the search page even if ?s was empty:

<?phpadd_filter('request', 'h5b_allow_empty_search');function h5b_allow_empty_search ($qryVars) {    if (isset($_GET['s']) and empty($_GET['s'])) {        $qryVars['s'] = ' ';    }    return $qryVars;}

Second, I told Relevanssi to fetch all posts if ?s was empty, by default it won't fetch any posts at all. Unfortunately, in doing this the default behaviour with custom taxonomies stopped working (my code over wrote it) so I had to manually check for taxonomies in this code as well:

<?phpadd_filter('relevanssi_hits_filter', 'h5b_allow_empty_search_filter');function h5b_allow_empty_search_filter ($hits) {    if (isset($_GET['s']) and empty($_GET['s']) and !count($hits[0])) {        $taxQry = array('relation' => 'AND');        if (!empty($_GET['custom_taxonomy'])) {            $taxQry[] = array(                'taxonomy' => 'custom_taxonomy',                 'field' => 'slug',                 'terms' => $_GET['custom_taxonomy']            );        }        $args = array(            'numberposts' => -1,             'post_type' => 'any'        );        if (count($taxQry) > 1) {            $args['tax_query'] = $taxQry;        }        $hits[0] = get_posts($args);    }    return $hits;}

And that's it. Everything seems to work and hopefully this will help someone who has similar requests in the future.

I really hope WP improves its ridiculous search in the future. Sorting by relevance should be something that's available in the world's most popular CMS imo.

Thanks @Sheikh Heera for pointing me in the right direction. I'm not sure who to give the right answer to though seeing as I really couldn't use the stuff you suggested.


Just found out that WP already has this in core.

In https://developer.wordpress.org/reference/classes/wp_query/, look at the "orderby" => "relevance" parameter.

Order by search terms in the following order: First, whether theentire sentence is matched. Second, if all the search terms arewithin the titles. Third, if any of the search terms appear in thetitles. And, fourth, if the full sentence appears in the contents.