I've been modifying the built in WP search using the pre_get_posts
filter, allowing the user to sort the posts (including a bunch of custom post types) by different fields.
The problem I'm having though is that when I tell WP to sort by a meta value it will exclude all posts that don't have that meta value set. This causes the number of results to change if you change sorting from say "Price" to "Date" because "Posts" don't have "Price" set but "Items" do.
This is not what I want, so I'd like to know if there's a way to include ALL posts - even those that lack the meta value I'm sorting on - and put the one's without the value last.
I know how to sort on more than one field but that doesn't help.
Thanks
Seems I'm not the only one with this question: Way to include posts both with & without certain meta_key in args for wp_query? but there's no solution there.
Update
I've tried the answer but not sure if I understood correctly, here's what I have right now:
<?php
function my_stuff ($qry) {
$qry->set('meta_query', array(array(
'key' => 'item_price',
'value' => '',
'compare' => 'NOT EXISTS'
)));
$qry->set('orderby', 'meta_value date'); # Sorting works with meta_value as well as meta_value_num - I've tried both
$qry->set('order', 'ASC DESC');
$qry->set('meta_key', 'item_price');
}
The meta value is a number (it is used to store a price as the name suggests)
Update 2
I've commented out the order-stuff and all I have now is this:
<?php
$qry->set('meta_query', array(array(
'key' => 'item_price',
'value' => '',
'compare' => 'NOT EXISTS'
)));
With this code the query seems to return all posts that don't have the item_price
key and none of the posts that have it. I.E. the problem is now reversed.
If I add in the order-code as well I get 0 results.
Edit: ...three years later... :P I had this issue again. I tried all the answers given and none work. Not sure why some people seem to think they work but they don't work for me at least.
The solution I ended up with is using the save_post
filter - making sure all posts have the custom field I wish to sort on. It's a bit annoying I have to do it, but at as long as you do it early on you'll likely have no issues.
In this case I was building a "view counter" on posts and wanted users to be able to sort on the most read posts. Again, posts that have never been viewed (I guess that's pretty unlikely - but still) disappeared when sorting on the view count. I added this bit of code to make sure all posts have a view count:
add_action('save_post', function ($postId) {
add_post_meta($postId, '_sleek_view_count', 0, true);
});
meta_query
andtax_query
are always anarray( array() )
as they combine multiple arrays. Second - as mentioned in my answer - you need to usemeta_value_num
for numbers. It might as well be needed to actually define themeta_value_num
(seeWP_Query
-Codex page entry). Last, it doesn't make sense toorder
inASC
andDESC
direction. That's not possible. The space delimiter only works fororderby
and you can't tell it to sort the firstASC
and the secondDESC
. That's whatposts_clauses
filter is for.meta_value_num
entries are real numbers. Seen it too often that someone states that it's a number, but in fact saving it as a string in the database.ASC DESC
is so that it sorts on themeta_value
inASC
and thedate
inDESC
, as far as I can tell it works.