Improve WordPress Search to Make it Search Exact Words.
The native wordpress search, does not look for exact complete words. It means that when you look for ‘Los’ you also get words like ‘lost’ ‘loser’ in search results. I found a lot of plugins which can improve search but found glitches in each of it. I decided to write my own solution. I needed a search which could look for exact word in posts. I implemented wordpress search for exact word in post titles using this code in functions.php.
// Search SQL filter for matching against post title only. function __search_by_title_only( $search, $wp_query ) { global $wpdb; if ( empty( $search ) ) return $search; // skip processing - no search term in query $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}[[:>:]]')"; $searchand = ' AND '; } if ( ! empty( $search ) ) { $search = " AND ({$search}) "; if ( ! is_user_logged_in() ) $search .= " AND ($wpdb->posts.post_password = '') "; } return $search; } add_filter( 'posts_search', '__search_by_title_only', 1000, 2 );
You can change this to search for exact words in titles plus content both, by modifying the line 18 to
Method 1:
$search .= "{$searchand}($wpdb->posts.post_title REGEXP '[[:<:]]{$term}[[:>:]]') OR ($wpdb->posts.post_content REGEXP '[[:<:]]{$term}[[:>:]]')";
The rest of code will remain same. Using the above snippets you will be able to improve wordpress search and make it exact word search.
I have come across another simpler solution, which be helpful, but the snippet posted above can be customized easily as much you need. So I would use method 1.
Method 2:
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; }
If you need to highlight search words, read here. I hope you like these wonderful snippets, happy coding!
14 comments
Khan
August 17, 2012 at 1:42 pm
Works like a charm sir, the rss feeds also show exact results 🙂
PMCDS
October 10, 2012 at 4:31 pm
Thank you;
You saved me so much time you have no idea! I truly appreciate that. Just for the future reference and those who are cutting/pasting the code as is, You may need to change a few HTML special characters like & to & or > to > signs. Also, there is a ” missing at the end of the line 18.
Great code.
Milan (PMCDS.ca)
Emerald
October 12, 2012 at 12:53 pm
Thanks for pointing out, i just updated the code.
Carlos
July 10, 2013 at 4:36 pm
Hello, this is exactly what i have been looking for, but i also need it to list categories…can you help me make it work to list all post whithin a category that match the search request? thanks in advance
Emerald
September 2, 2013 at 7:24 am
Hi Carlos,
Thanks. That can be done by changing the action url of search form to
http://www.mysite.com/category/mycat
where ‘mycat’ is the category i want to search for those words. Hope this helps.
Pingback: Make WordPress Search…Exact! | tinyGod
Hendarta
December 17, 2014 at 1:00 pm
Hello,
I search “F” and get John F. Kennedy, F-1, F.D.R., etc.
I mean some chars such as coma, dot, etc. still follow.
BTW, thank you.. this helps me much.
Cheers!
Gifford
August 19, 2015 at 2:57 pm
Thank you for your fantastic code, it really saved me!
Taking this a step further you can also add taxonomy names to the “exact-match search” by replacing the existing line with the following:
$search .= “{$searchand}(
$wpdb->posts.post_title REGEXP ‘[[::]]’)
OR ($wpdb->posts.post_content REGEXP ‘[[::]]’)
OR ((SELECT COUNT(wp_terms.term_id) FROM wp_term_relationships
LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
LEFT JOIN wp_terms ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE (wp_term_relationships.object_id = $wpdb->posts.ID)
AND (wp_terms.name REGEXP ‘[[::]]’)) > 0)
“;
This particularly helps if you are trying to find WooCommerce products by category, as the existing code does not find them.
I hope others find this useful.
Cheers!
Yumna Tatheer
December 30, 2016 at 6:22 am
Thanks Gifford, I have not tested it though.
Jay
May 13, 2017 at 8:01 am
using this code… how can i include acf custom fields?
Yumna Tatheer
April 8, 2018 at 9:11 am
For custom fields you will have to look in post_meta, this code wont work.
Pingback: WordPress – bionyt.dk
Luca
November 19, 2018 at 8:48 pm
I’m using this code and it lists posts whose titles contain an exact match, but I also require all other non-exact matches to be listed after the exact matches.
For example, if I search “ABC”, this code will list posts with titles like “ABC” and “ABC 1”. But I also need it to list posts with titles like “ABCD” after all the exact matches.
Is there a way to modify this code so that it “defaults” to non-exact matches after all the exact matches have been listed?
Thank you, and thanks for the helpful post.
Smix
December 5, 2018 at 10:01 am
Hi. Is there a way we can narrow down search within only 2-3 first words in title?
My posts title look like this (they contain name of company and keywords):
Flower in you Ltd. | A florist and arranger shop Flower box, flower decorations, wedding bouquets, funeral wreaths, flower delivery, gift arrangements, weddings, decorations for celebrations, decorations of business premises, innovative flower decorations, dry and fresh flowers, florist services in Samobor.
I would like to achieve a search box that would search by the title of company exclusively and since in post title there is company name and keywords..Can this be done?
Tnx