I need help with sorting search results by a custom field called product_ratings. Here’s my current approach:
function custom_search_ordering($wp_query) {
if ($wp_query->is_search()) {
$wp_query->set('orderby', 'meta_value_num');
$wp_query->set('meta_key', 'product_ratings');
$wp_query->set('order', 'DESC');
}
}
add_action( 'pre_get_posts', 'custom_search_ordering', 999 );
The function looks correct to me, but it’s not working as expected. When I perform a search, the ordering remains unchanged. My search URL appears as ?s=blue+shirt&post_type=product but the generated query shows:
SELECT SQL_CALC_FOUND_ROWS wp_posts.*, ID, (MATCH(post_title) AGAINST ('blue shirt' ) * 1 ) + (MATCH(post_content) AGAINST ('blue shirt' ) * 10 ) AS score
FROM wp_posts
INNER JOIN wp_postmeta
ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE 1=1
AND MATCH (post_title,post_content) AGAINST ('blue shirt' )
AND (post_status = 'publish'
OR post_status = 'inherit')
AND wp_posts.post_type IN ('product')
GROUP BY wp_posts.ID
ORDER BY score DESC
LIMIT 0, 12
Why isn’t my custom meta field ordering being applied to the search query?
you’re missing the is_main_query() check - that’ll cause conflicts. add && $wp_query->is_main_query() to your if condition. also, that SQL shows WordPress is still using relevance score ordering instead of your meta field. maybe another plugin’s overriding it?
Just dealt with this exact issue last month on a client project. WordPress search queries have their own ordering system that overrides your pre_get_posts changes. Your code looks right, but search queries get processed differently than regular post queries. What fixed it for me was adding a priority check and making sure the meta query joins properly. Try this instead: php function custom_search_ordering($wp_query) { if (!is_admin() && $wp_query->is_search() && $wp_query->is_main_query()) { $wp_query->set('meta_query', array( array( 'key' => 'product_ratings', 'compare' => 'EXISTS' ) )); $wp_query->set('orderby', 'meta_value_num'); $wp_query->set('meta_key', 'product_ratings'); $wp_query->set('order', 'DESC'); } } The meta_query forces WordPress to join the postmeta table properly - that’s probably why your ordering isn’t working. Also check if you’ve got any search plugins that might mess with the query structure.
It appears that the relevance scoring is affecting your custom meta field ordering. The SQL query indicates that ORDER BY score DESC is still being applied, possibly due to conflicts with another plugin or a custom search feature. Instead, consider using the posts_orderby filter, which allows you to modify the ORDER BY clause after the query is constructed. Here’s an example:
function override_search_orderby($orderby, $wp_query) {
if ($wp_query->is_search() && $wp_query->is_main_query()) {
global $wpdb;
return "$wpdb->postmeta.meta_value+0 DESC";
}
return $orderby;
}
add_filter('posts_orderby', 'override_search_orderby', 10, 2);
Implementing this should ensure that your custom ordering takes precedence.