Using a Custom Field to Prioritize Search Results
Note: This documentation is for SearchWP 3.x
SearchWP 4: Using a Custom Field to Prioritize Search Results
By default, SearchWP returns search results ordered by calculated weight descending. In other words the most relevant results bubble to the top based on the weights you’ve set on the settings screen for your search engine. That allows you to custom tailor the results to the content of your site to a very high degree. Sometimes you’d like another level of control, however.
SearchWP allows you to create a ‘buoy’ of sorts. You can use a Custom Field of your choice to store numerical values that will be given priority over SearchWP’s calculated weights for search results. You can use this to have certain posts rise to the top of search results based on this Custom Field value.
See also: Add Weight to More Recently Published Entries
To create the buoy, you can use a couple of SearchWP’s many Hooks, by adding the following to your theme’s functions.php
:
<?php | |
function my_searchwp_query_main_join( $sql, $engine ) { | |
global $wpdb; | |
$my_meta_key = 'my_search_priority'; // the meta_key you want to order by | |
$sql = $sql . " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '{$my_meta_key}'"; | |
return $sql; | |
} | |
add_filter( 'searchwp_query_main_join', 'my_searchwp_query_main_join', 10, 2 ); | |
function my_searchwp_query_orderby( $orderby, $engine ) { | |
global $wpdb; | |
$my_order = "DESC"; // use DESC or ASC | |
$original_orderby = str_replace( 'ORDER BY', '', $orderby ); | |
if ( "DESC" === $my_order ) { | |
// Sort in descending order | |
$new_orderby = "ORDER BY {$wpdb->postmeta}.meta_value+0 DESC, " . $original_orderby; | |
} else { | |
// Sort in ascending order; place empties last | |
// @link http://stackoverflow.com/questions/2051602/mysql-orderby-a-number-nulls-last#8174026 | |
$new_orderby = "ORDER BY -{$wpdb->postmeta}.meta_value+0 DESC, " . $original_orderby; | |
} | |
return $new_orderby; | |
} | |
add_filter( 'searchwp_query_orderby', 'my_searchwp_query_orderby', 30, 2 ); |
There are two filters in use here: searchwp_query_main_join
and searchwp_query_orderby
. Combined, they modify SearchWP’s main search query to give priority to your Custom Field and it’s values.
Take note of the first function, my_searchwp_query_main_join()
. You’ll notice that there is a $my_meta_key
variable present. You will need to customize this to match the Custom Field key you are using to store numeric weights that should be given priority over SearchWP’s calculated weights. That is the only thing you’ll need to customize.
Next is the my_searchwp_query_orderby()
function. In this function there is a variable named $my_order
that controls the order in which your Custom Field values will be placed when returning results. By default it is DESC
but you can change that to ASC
if you want your search results to be ascending (e.g. from 1 to 10 instead of 10 to 1).
What if only some posts have the Custom Field?
The good thing about this implementation is that not every post in your index needs to have this Custom Field, it’s simply given priority when present. Posts without the Custom Field will simply fall in line below those that do. Posts that have the same Custom Field value will be first ranked by that value, and then secondarily ranked by their SearchWP calculated weight.