Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wordpress, multiple meta_key in pre_get_posts

Tags:

wordpress

is it possible to add two meta_key's in pre_get_posts?

my current query

$query->set('s', '' ); 
$query->set( 'meta_key', 'cat_adresse_stadtteil' );
$query->set( 'meta_value', array('charlottenburg', 'wilmersdorf', 'schmargendorf') ); 

add this

$query->set('orderby','meta_value_num');
$query->set('meta_key', 'rank');
$query->set('order', 'ASC');  



EDIT
Ok, i found this solution (link #example 2)

$args = array(
    'numberposts' => -1,
    'post_type' => 'event',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'location',
            'value' => 'Melbourne',
            'compare' => '='
        ),
        array(
            'key' => 'attendees',
            'value' => 100,
            'type' => 'NUMERIC',
            'compare' => '>'
        )
    )
);

but it doesnt work, any ideas what is wrong?

$query->set('meta_query',array(
             array( 'key' => 'cat_adresse_stadtteil',
                    'value' => array('charlottenburg', 'wilmersdorf', 'schmargendorf'), ),
            array(  'key' => 'rank'
                    'orderby' => 'meta_value_num',
                    'order' => 'ASC' ) ) ); 
like image 471
user2306309 Avatar asked Oct 16 '14 00:10

user2306309


2 Answers

To combine the two parts, you can try the following:

add_action( 'pre_get_posts', function( $q ) {    

    // Only modify the main query on the front-end:
    if( ! is_admin() && $q->is_main_query() )
    {
        $meta_query = array(
          array(
            'key'     => 'cat_adresse_stadtteil',
            'value'   => array('charlottenburg', 'wilmersdorf', 'schmargendorf'),
            'compare' => 'IN',
          ),
        );
        $q->set( 'meta_query', $meta_query      );
        $q->set( 'meta_key',   'rank'           );
        $q->set( 'orderby',    'meta_value_num' );
        $q->set( 'order',      'ASC'            );
        $q->set( 's',          ''               );
    }
});

It looks like you were missing the compare parameter and using the order and orderby parameters in a wrong place. I'm not sure though why you are resetting the search parameter.

The generated SQL query will look something like:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
    FROM wp_posts 
    INNER JOIN wp_postmeta
        ON (wp_posts.ID = wp_postmeta.post_id)
    INNER JOIN wp_postmeta AS mt1
        ON (wp_posts.ID = mt1.post_id)
    WHERE 1=1 
        AND wp_posts.post_type 
            IN ('post', 'page', 'attachment' )
        AND (wp_posts.post_status = 'publish'
            OR wp_posts.post_author = 1
            AND wp_posts.post_status = 'private')
        AND (wp_postmeta.meta_key = 'rank'
        AND (mt1.meta_key = 'cat_adresse_stadtteil'
        AND CAST(mt1.meta_value AS CHAR) 
            IN ('charlottenburg','wilmersdorf','schmargendorf')) )
    GROUP BY wp_posts.ID
    ORDER BY wp_postmeta.meta_value+0 ASC
    LIMIT 0, 10
like image 183
birgire Avatar answered Nov 08 '22 03:11

birgire


You can convert this query to pre_pget_posts:

$meta_query_args = array(
    'relation' => 'AND', // "OR"
    array(
        'key'     => '_my_custom_key',
        'value'   => 'Value I am looking for',
        'compare' => '='
    ),
    array(
        'key'     => '_your_min_model_key',
        'value'   => 1453,
        'compare' => '>'
    ),
    array(
        'key'     => '_your_max_model_key',
        'value'   => 1923,
        'compare' => '<'
    )
);
$meta_query = new WP_Meta_Query( $meta_query_args );

And compare param details:

compare (string) - Operator to test. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS' (only in WP >= 3.5), and 'NOT EXISTS' (also only in WP >= 3.5). Values 'REGEXP', 'NOT REGEXP' and 'RLIKE' were added in WordPress 3.7. Default value is '='. 
like image 7
Fatih SARI Avatar answered Nov 08 '22 03:11

Fatih SARI