In order for sorting by a meta value to work, the meta_key
parameter is required (source):
Note that a
meta_key=keyname
must also be present in the query.
Unfortunately this will result in only posts with the meta key set to be found by the query.
From here there are two options:
- Use a query to get all the posts, and sort the posts using PHP.
- Execute multiple queries and combine the results.
Each option has difficulties, but I would suggest the second, as you can execute an additional query with the post IDs, to support pagination (untested):
$posts_with_rating = new WP_Query( array(
'posts_per_page' => -1,
'meta_key' => 'rating',
'fields' => 'ids',
'orderby' => array(
'meta_value_num' => 'DESC',
'date' => 'DESC',
),
) );
$posts_without_rating = new WP_Query( array(
'posts_per_page' => -1,
'fields' => 'ids',
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'rating',
'compare' => 'NOT EXISTS',
),
),
) );
$combined = new WP_Query( array(
'post__in' => array_merge( $posts_with_rating->posts, $posts_without_rating->posts ),
'orderby' => 'post__in',
) );