2 orderby in wp_query with 2 custom fields

I’m triyng to display hotels (taxonomy which i have created) by two ‘orderby’ with wp_query but i’m not success.

Results looks likes:

Read More
Hotel 1 :       2 persons          5 stars
Hotel 2 :       2 persons          4 stars
Hotel 3 :       2 persons          3 stars
Hotel 4 :       3 persons          5 stars
Hotel 5 :       5 persons          5 stars
Hotel 6:        10 persons         2 stars
Hotel 7:        10 persons         1 star

The first ‘order by’ is on the number of persons(the biggest in first) and the second ‘order by’ is on the rating in stars (so, if several hotels have the same number of persons, the hotel with the biggest stars rating would be in first).

Below my code. I have tried to add an array inside an array with meta_query but it doesn’t work.

$args=
            array(
                                    'post_type' => 'hotel',
                                    'Services' => $Services,
                                    'Town' => $Town, 
                                    'meta_key' => 'Number_persons',
                                    'orderby' => 'meta_value_num',
                                    'order' => 'ASC',   
                                    'meta_query' => array(
                                                           array(
                                                               'meta_key' => 'Rating',
                                                               'orderby' => 'meta_value',
                                                               'order' => 'DESC',   
                                                           )
                                                       )
                 );


$the_query = new WP_Query( $args );

Thanks a lot 🙂

Related posts

1 comment

  1. If you look at the Codex for WP_Query you will notice that orderby is not a valid parameter for a meta_query, nor is order, and in fact nor is meta_key.

    But even if that were sorted out, I don’t think you can do what you are trying to do with WP_Query. A meta_query is a WHERE clause element, which makes it a kind of search and I don’t think that is what you want. If all of your posts have those keys set then EXISTS might get you part of the way there, but it would exclude anything without one of those keys. Something like this:

    'meta_query' => array(
        array(
            'key' => 'Rating',
            'compare' => 'EXISTS'
        ),
        array(
            'key' => 'Number_persons',
            'compare' => 'EXISTS'
        )
    )
    

    But ordering is still a problem and I don’t see a way around it other than a filter on posts_orderby.

    function double_meta_posts_orderby($orderby) {
      global $wpdb;
      return " {$wpdb->postmeta}.meta_value, mt1.meta_value";
    }
    

    And put all together…

    $args = array(
    'post_type' => 'hotel',
        'Services' => $Services,
        'Town' => $Town, 
        'meta_query' => array(
      array(
            'key' => 'Number_persons',
            'compare' => 'EXISTS'
          ),
          array(
            'key' => 'Rating',
            'compare' => 'EXISTS'
          ),    
    )
    );
    add_filter('posts_orderby','double_meta_posts_orderby');
    $query = new WP_Query( $args );
    remove_filter('posts_orderby','double_meta_posts_orderby');
    

    Again, that is only going to work if all of your posts have those meta_keys. You could use the posts_joins to join the meta table yourself or you could just remove the WHERE clause with…

    function kill_where($where) {
      return '';
    }
    add_filter('posts_where','kill_where');
    

    Note that you are adding the filters and then removing it immediately after the query runs. If you want to avoid the need for that take a look at this answer for another option, or make the filters self-removing…

    function double_meta_posts_orderby($orderby) {
      remove_filter('posts_orderby','double_meta_posts_orderby');
      global $wpdb;
      return " {$wpdb->postmeta}.meta_value, mt1.meta_value";
    }
    

Comments are closed.