admin管理员组

文章数量:1188422

I have been told here that having my data saved as metadata is creating slow queries.

I'm starting to convert all data used to sort my posts to taxonomy data. I've converted all the data stored in 'wpcf-release-year' to a taxonomy called 'release-year' and have created terms for every year.

Now I'd like to sort posts by release-year. I can't seem to find a way to get this to work with my new taxonomy. Here's my old code

$my_query_args = array( 
    'posts_per_page' => -1,
    'post_type' => 'release',
    'meta_key'       => 'wpcf-release-year', //I want this to be my taxonomy instead of the meta data
    'orderby'        => array(
        'meta_value_num' => 'ASC',
        'title' => 'ASC',
    ),               
    'tax_query' => $release_type_query,
);

How can I refer to the taxonomy term instead of the meta-key in this code? I've tried using the name meta_key => 'release-year' but that made all the posts dissapear. Do I need to add a new tax query? I'm not sure what to do. Thanks!

I have been told here that having my data saved as metadata is creating slow queries.

I'm starting to convert all data used to sort my posts to taxonomy data. I've converted all the data stored in 'wpcf-release-year' to a taxonomy called 'release-year' and have created terms for every year.

Now I'd like to sort posts by release-year. I can't seem to find a way to get this to work with my new taxonomy. Here's my old code

$my_query_args = array( 
    'posts_per_page' => -1,
    'post_type' => 'release',
    'meta_key'       => 'wpcf-release-year', //I want this to be my taxonomy instead of the meta data
    'orderby'        => array(
        'meta_value_num' => 'ASC',
        'title' => 'ASC',
    ),               
    'tax_query' => $release_type_query,
);

How can I refer to the taxonomy term instead of the meta-key in this code? I've tried using the name meta_key => 'release-year' but that made all the posts dissapear. Do I need to add a new tax query? I'm not sure what to do. Thanks!

Share Improve this question asked Oct 4, 2022 at 15:57 DJZEEGLERDJZEEGLER 11911 bronze badges 2
  • 1 Did you try actually using orderby as just a string? 'orderby' => 'meta_value_num' . The ASC is actually a separate arg value order. – rudtek Commented Oct 4, 2022 at 16:18
  • i tried both 'orderby' => 'release-year' and meta_key' => 'release-year', 'orderby' => 'meta_value_num'. The first orders them by title. The second shows no results. – DJZEEGLER Commented Oct 4, 2022 at 16:24
Add a comment  | 

3 Answers 3

Reset to default 2

You can't order by taxonomy terms, the very concept breaks down when you try to handle posts that have multiple terms in a taxonomy. You may know that only 1 term will ever be selected but WP_Query isn't built that way.

Instead, keep your taxonomy so that you retain all the performance/theming/Admin UI benefits, but also save the information in post meta so that you can sort. This way you get the best of both worlds, and you can automate updating the post meta when the terms change. This also lets you use post meta sorting with tax_query.

While this does lead to duplication the cost is minimal, and the performance gains are very real. You may even decide to store data in the future that's only ever used to improve performance, e.g. intermediate pre-calculated data, or buckets ( e.g. storing a price in post meta, but putting the posts into predefined buckets such as $100-$150 )

There's a lot to unpack here so I'm going to give it my best shot.

Your basic code I would change to this:

$my_query_args = array( 
    'posts_per_page' => -1,
    'post_type' => 'release',
    'meta_key'       => 'release-year',
    'orderby'        => 'meta_value_num',
    'order'          => 'ASC',              
    'tax_query' => $release_type_query,
);

I changed your meta key to your custom taxonomy release-year. Additionally I stripped your orderby arg to just sort by numbers.

This will ONLY work if all your terms in release-year are actually all numbers.

This being said...what you're doing doesn't seem to make sense. I think using post meta is a MUCH better option. If the above doesn't work Check this question: Using wp_query is it possible to orderby taxonomy?

Actually, it IS possible to get the main query to sort by taxonomy... it just isn't really pretty. First and foremost: this will work by manipulating the query that is executed by WordPress. If you don't know your way around the WordPress database, i would probably not recommend doing this because you could f up your website. But let's get into the meat of things, okay?

Step 1: Add the Filter

First and foremost, i am assuming that you want to order the "releases" on the "release"-Post-Type-Archive.

To change the SQL-Query performed by WordPress directly, you can use the filter "posts_clauses", which you can get more information on here.

To add the filter only on the archive of the custom post type, we will use the pre_get_posts filter like this:

add_action('pre_get_posts','setup_my_query_interception');

function setup_my_query_interception($query){
    if( !is_admin() && $query->is_post_type_archive( 'release' ) && $query->is_main_query() ){
     add_filter( 'posts_clauses', 'order_by_taxonomy_intercept_query_clauses', 20, 1 );
  }
}

The Database Query Pieces will now be sent to our function order_by_taxonomy_intercept_query_clauses (which will be in step 2) before being executed.

Step 2: Change the query

We have to extend the MySQL Query to include the term and taxonomy tables. We use the Filter-Function order_by_taxonomy_intercept_query_clauses for this.

function order_by_taxonomy_intercept_query_clauses($pieces){
        global $wpdb;
        $pieces['join'].=" LEFT JOIN $wpdb->term_relationships trt ON ($wpdb->posts.ID = trt.object_id) LEFT JOIN $wpdb->term_taxonomy ttt ON (trt.term_taxonomy_id = ttt.term_taxonomy_id) INNER JOIN $wpdb->terms termts ON (termts.term_id = ttt.term_id)";
        $pieces['where'].=" AND ttt.taxonomy = 'release-year'";
        $pieces['orderby']="termts.name ASC, ".$pieces['orderby'];
        //Remove the filter so it only runs once in our main query
        remove_filter('posts_clauses', 'order_by_taxonomy_intercept_query_clauses');
        return $pieces;
}

Step 3: Success!

Your Releases will now be ordered by release-year.

Happy Coding!

本文标签: orderHow to orderby Taxonomy Term in a WP Query