Make a WP Query search match exactly the search term

This is actually a tricky question, as by stating exact there are two ways in which one can interprit your question –

  1. Only find posts where the whole title or the whole content match exactly. For example, if you search My post is super you would not have returned a post with the title My post is super awesome.
  2. Fine posts where the exact phrase exists, not just part of a phrase. For example, if you search his house you would not have returned a post with the title I love this house, but you would a post with the title I’m going to his house (rubish examples, but hopefully you get the point).

Luckily you can do either, but method 1 is by far the simpler. Add either of these examples to your functions.php file –


Method 1

add_action('pre_get_posts', 'my_make_search_exact', 10);
function my_make_search_exact($query){

    if(!is_admin() && $query->is_main_query() && $query->is_search) :
        $query->set('exact', true);
    endif;

}

The my_make_search_exact() function will be called everytime a query is made, using the pre_get_posts action hook.

To ensure we don’t mess with the query when we don’t need to, within the function we check that we are NOT viewing the admin area, that we ARE constructing the main query and that we ARE making a search.


Method 2

add_filter('posts_search', 'my_search_is_exact', 20, 2);
function my_search_is_exact($search, $wp_query){

    global $wpdb;

    if(empty($search))
        return $search;

    $q = $wp_query->query_vars;
    $n = !empty($q['exact']) ? '' : '%';

    $search = $searchand = '';

    foreach((array)$q['search_terms'] as $term) :

        $term = esc_sql(like_escape($term));

        $search.= "{$searchand}($wpdb->posts.post_title REGEXP '[[:<:]]{$term}[[:>:]]') OR ($wpdb->posts.post_content REGEXP '[[:<:]]{$term}[[:>:]]')";

        $searchand = ' AND ';

    endforeach;

    if(!empty($search)) :
        $search = " AND ({$search}) ";
        if(!is_user_logged_in())
            $search .= " AND ($wpdb->posts.post_password = '') ";
    endif;

    return $search;

}

Credit to tinyGod for this answer – http://tinygod.pt/make-wordpress-search-exact/

Leave a Comment