WP Query - Order by metavalue and keep other posts - php

Can't figure out this problem. Goal: I want to show all posts and order them by a post meta value, but not all posts have that meta key.
Problem: Not all posts are shown, only the ones that have that meta key (and meta value).
$args = array(
'post_type' => 'post',
'meta_key' => 'post_custom_field_1',
'orderby' => 'meta_value',
'order' => 'ASC',
'paged' => $paged,'post_type' => 'post' );
Question: How can I show all posts and sort them by a meta_key? Posts that have the meta_key are shown first and ordered by name and posts that don't have the meta_key follow and are sorted by title.

You'll have to use EXISTS for compare. There are plenty of examples in the docs for WP_Query, you can adapt it to your case:
function orderby_fieldifexists($orderby) {
return "mt1.post_id IS NOT NULL DESC, wp_postmeta.meta_value ASC";
}
add_filter("posts_orderby", "orderby_fieldifexists", 10, 1);
$query = new WP_Query(
array(
'post_type' => 'post',
'meta_query' => array(
"relation" => "or",
'custom_field_value' => array(
'key' => 'post_custom_field_1',
),
'custom_field' => array(
'key' => 'post_custom_field_1',
'compare' => 'NOT EXISTS',
),
),
'orderby' => array(
'custom_field' => 'ASC'
),
'posts_per_page' => 5,
)
);
I've initially had a simpler version in here, but then remembered that it would be silly to sort numerically if some values will be NULL. This version will find all posts, but get the value as well, and sort descending on "does it exist?" and then ascending on the actual values, so a post with a custom field value of -1 will be listed before those without that custom field value.

Related

Filter wordpress query by numerical order arguments

I have some programs that go according to the day but I want it to be filtered by custom field such as menu_order, that is, by numerical position through ordernum that I can give it
This doesn't show me the result. ordernum is a select field with integers
$args = array(
'post_type' => 'schedule',
'posts_per_page' => -1,
'meta_key' => 'day',
'meta_value' => 'Sunday',
'meta_query' => array(
array(
'key' => 'ordernum',
'value' => 'meta_value_num',
'compare' => '=',
),
)
);
Your meta query at the moment is filtering the results by the custom field "ordernum" with the value "meta_value_num". It seems like your value is wrong. If you want to filter the results for only posts which have ordernum = 1, then change the value to "1".
If you want to order your query by the ordernum field, you will need to add the following args
$args = array(
'orderby' => 'ordernum',
'order' => 'DESC',
);

Sort wp_query by multiple meta keys (numeric) in specific order

I need to sort a query by a specific order and I failed many times on finding the right solution, but nothing helped – so I'm asking for some hints what I'm doing wrong.
Short story: I have a wp_query showing bikes ordered by the cheapest price. It's working so far. But now I want to show some promotional bikes at first before the order by price starts. So the promotional bikes are showing first and then the "normal" loop.
Promotional bikes are tagged by a ACF field called "promotional_bikes".
This is my wp_query:
$args = array(
'post_type' => 'bikes',
'posts_per_page' => -1,
'facetwp' => true,
'post_status' => 'publish',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_key' => 'baseprice_0_rate', // it's a repeater field in acf
);
meta_key = baseprice_0_rate
meta_value = 100 - 1000 // different values because of the prices
meta_key = promotional_bike
meta_value = 1 // because true or false in acf
This was my last try:
$args = array(
'post_type' => 'bike',
'posts_per_page' => -1,
'facetwp' => true,
'post_status' => 'publish',
'meta_query' => array(
'promo_bike' => array(
'key' => 'promotional_bike',
'compare' => 'EXISTS',
),
'cheapest_bikes' => array(
'key' => 'baseprice_0_rate',
'compare' => 'EXISTS',
),
),
'orderby' => array(
'promotional_bike' => 'ASC',
'cheapest_bikes' => 'meta_value_num',
)
);
but I get 0 results and it doesnt work.
Can anybody give me a hint how to first show the promo bikes and then show the bikes (cheap to high) ?
Many thanks :-)
I came across this while trying to figure out how to orderby multiple numeric meta fields. Finally got it figured out and wanted to post some tips in case anyone else arrives here for the same reason.
Assuming the OP's query had returned results, here's how to sort by multiple numeric meta fields. The key is the type attribute when defining the meta_query clauses.
$args = [
'post_type' => 'bike',
'posts_per_page' => -1,
'facetwp' => true,
'post_status' => 'publish',
'meta_query' => [
'promo_bike' => [
'key' => 'promotional_bike',
'compare' => 'EXISTS',
'type' => 'NUMERIC', // makes orderby sort numerically instead of alphabetically
],
'cheapest_bikes' => [
'key' => 'baseprice_0_rate',
'compare' => 'EXISTS',
'type' => 'NUMERIC',
],
],
'orderby' => [
'promo_bike' => 'DESC', // assuming you want promotional_bike=1 at the top
'cheapest_bikes' => 'ASC',
],
]
Sources:
https://ideone.com/RUoyZs
https://wordpress.stackexchange.com/questions/246355/order-by-multiple-meta-key-and-meta-value
you don't need to code for that. simply you can short your product from Category>Count and then you can drag & drop... for better understanding - you can see my video tutorial.

Wordpress orderby meta values in array

I'm trying to get sorted list of posts using get_posts by meta value and the order of meta value is given in array.
This is what I currently have.
$stores = get_posts(array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids', // I only need the ID's of posts
'orderby' => 'meta_value',
'meta_key' => 'state',
'order' => 'ASC'
));
This returns the array of posts sorted by meta_value in ASCENDING alphabetical order.
I have an array of possible values for 'meta_key' => 'state', i.e. array('State1', 'State2', 'State3')
I want to set order so that all stores which has meta value State1 appears first, then from State2 and after that State3
I can't use order by numeric value and alphabetical value as state names are gonna be random.
I found one post here, it is using mera_query_orderby. I can't find any documentation for this and tried it, but it's not working. It returns posts ordered by ID.
Any help would be appreciated. Thanks
EDIT:
I added the meta_query_orderby filters in functions.php
And the updated code I used from EXAMPLE 2, is like:
$stores = get_posts(array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'state', // Custom field key.
'value' => array("CState1", "AState2", "BState3")
)
),
'meta_query_orderby' => array(
array(
'key' => 'state', // (required) Custom field key.
'value' => array("CState1", "AState2", "BState3")
)
)
));
I have an array of possible values for 'meta_key' => 'state', i.e.
array('State1', 'State2', 'State3')
If you want to sort the posts by the meta value in the exact order as in the above array, you can use a custom WP_Query parameter (to set the meta/sort values) and the posts_orderby filter to customize the ORDER BY clause, and in that clause, you would be using the FIELD() function in MySQL.
Step 1
Add this code to your plugin or theme (if theme, you'd add the code to the theme functions file):
add_filter( 'posts_orderby', 'posts_orderby_meta_value_list', 10, 2 );
function posts_orderby_meta_value_list( $orderby, $query ) {
$key = 'meta_value_list';
if ( $key === $query->get( 'orderby' ) &&
( $list = $query->get( $key ) ) ) {
global $wpdb;
$list = "'" . implode( wp_parse_list( $list ), "', '" ) . "'";
return "FIELD( $wpdb->postmeta.meta_value, $list )";
}
return $orderby;
}
Step 2
When making your post queries, set the orderby to meta_value_list and add meta_value_list to the query parameters — if you're using get_posts(), make sure suppress_filters is set to false:
$stores = get_posts( array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids', // get just the ID's of posts
'meta_key' => 'state',
'orderby' => 'meta_value_list',
'meta_value_list' => array( 'State1', 'State2', 'State3', '' ),
'suppress_filters' => false,
) );
PS: I the added '' to the array so that posts where the metadata is ('') (i.e. exists in the database, but the value is empty) would be placed at the bottom of the results.
Tried and tested working, but note that the above solution is only for single orderby, which means array is not supported.
/*Display posts of type 'stores', ordered by 'state', and filtered to show only states.*/
$args = array(
'post_type' => 'stores',
'meta_key' => 'state',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'state',
'value' => array( 'State1', 'State2', 'State3'),
'compare' => 'IN',
),
),
);
$query = new WP_Query( $args );

Wordpress sort by number custom fields gives different results

I have a query which gives me custom post type posts which are sorted by category and a custom fields which has a number that indicates the amount of votes for the post. The problem is, if 2 posts have 3 votes, sometimes when you refresh, it changes their position. Here is the code:
$args = array(
'numberposts' => 10,
'post_type' => 'nominees',
'meta_query' => array(
array(
'key' => 'category',
'value' => get_the_ID(),
'compare' => '=',
)
),
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_key' => 'count_nominees'
);
I tried adding order on the category meta query, but nothing changes, I still sometimes get different results when refreshing, if the posts have same amount of votes. What is the right way to add second order, by ID or something?
Thanks.
As mentioned in the comments, I think this might help, but you might be able to extend it to be a little more specific in the search query for your use case.
$args = array(
'numberposts' => 10,
'post_type' => 'nominees',
'meta_query' => array(
array(
'key' => 'category',
'value' => get_the_ID(),
'compare' => '='
)
),
'meta_key' => 'count_nominees',
'orderby' => array(
'count_nominees' => 'DESC',
'ID' => 'DESC'
)
);
That should get 10 posts in the nominees post type, only if they're part of category xyz, and have post meta of count_nominees and order by count_nominees first in descending order and then by the post ID in descending order.
You can use the WP_Query documentation on the WordPress codex for more information about complex queries using post meta data.

Wordpress AJAX Load More Orderby Meta_VALUE_NUM

Helo,
I have multiple meta_key value pairs inside my custom posts. So to work around this what I did is that I ran a WP_QUERY initially which creates an array of posts ID which I then pass to load more to load those.
The array that I build using WP_Query is in the correct order. However when I use the IDs in post_in parameter it is not displaying them in the given order. I have also tried to give orderby="meta_value_num" parameter but it doesnt work either.
Here is WP_QUERY which is working perfectly
$loop = new WP_Query(
array(
'post_type' => 'properties',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'listing_type',
'value' => array(3,2),
'type' => 'NUMERIC',
),
array(
'key' => 'payment_status',
'value' => 'yes',
),
array(
'key' => 'expired',
'value' => 'no',
- ),
),
'orderby' => 'meta_value_num',
'meta_key' => 'listing_type',
'order' => 'DESC'
));
Here is the shortcode:
[ajax_load_more post_type="properties" post__in="'.implode(',',$featured).'" posts_per_page="10" scroll="false" transition="fade" button_label="'.$l_more.'" button_loading_label="'.$l_more_2.'" container_type="ul" css_classes="items",orderby="meta_value_num" meta_key="listing_type"]
However it doesnt order posts as it should because $featured array has it in required order. Even if I remove order by and meta_key parameter it doesnt work.
Please Help
Ahmar
First, you have an error in your shortcode.
[ajax_load_more post_type="properties" post__in="'.implode(',',$featured).'" posts_per_page="10" scroll="false" transition="fade" button_label="'.$l_more.'" button_loading_label="'.$l_more_2.'" container_type="ul" css_classes="items" orderby="meta_value_num" meta_key="listing_type"]
Second, you should orderby="post__in" to preserve the post__in ordering.
https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters

Categories