11

I want to use the WP_Query() class to filter some of my posts. The problem I am facing now is handling the taxonomy query. Normally, the WP_Query() only handle one relationship for tax_query() (either AND or OR), but what I need is mixed use of these relationships on the tax_query(), how can achieve it?
eg

'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'taxonomy1',
            'field' => 'slug',
            'terms' => array( $term)
        ),
        array(
            'taxonomy' => 'taxonomy3',
            'field' => 'slug',
            'terms' => 'terms' => array( $term3),
            'operator' => 'IN',
        )
       // below i want to use OR relationship
       'relation' => 'OR',
      array(
            'taxonomy' => 'taxonomy4',
            'field' => 'slug',
            'terms' => array( $term4)
        ),
        array(
            'taxonomy' => 'taxonomy2',
            'field' => 'slug',
            'terms' => 'terms' => array( $term2),
            'operator' => 'IN',
        )
    )  

I know the code above is not working, do I need to use WP_Query() filter to do it? Any idea?

11

This can be done by using the term_taxonomy_id rather than the slug, which will effectively ignore whichever taxonomy is specified and just look at the unique term_taxonomy_id field. This will allow you to effectively be able to do a mixed relationship. You'd want to use an overall relation of AND and put all the terms that should be related OR in one item using the IN operator. You will need to map the terms desired to their term_taxonomy_ids first.

$taxes = array( 'taxonomy1', 'taxonomy2', 'taxonomy3', 'taxonomy4' );

foreach ( $taxes as $tax ) {
    $terms = get_terms( $tax );

    foreach ( $terms as $term )
        $tax_map[$tax][$term->slug] = $term->term_taxonomy_id;
}


$args['tax_query'] => array(
    'relation' => 'AND',
    array(
        'taxonomy' => 'taxonomy1',
        'field' => 'term_taxonomy_id',
        'terms' => array( $tax_map['taxonomy1'][$slug] )
        'operator' => 'IN',
    ),
    array(
        'taxonomy' => 'taxonomy3',
        'field' => 'term_taxonomy_id',
        'terms' => array( $tax_map['taxonomy3'][$slug] ),
        'operator' => 'IN',
    ),
    array(
        'taxonomy' => 'taxonomy4', // gets ignored
        'field' => 'term_taxonomy_id',
        'terms' => array( $tax_map['taxonomy4'][$slug], $tax_map['taxonomy2'][$slug] ),
        'operator' => 'IN',
    ),
);

Note that pre-3.5, you'd also need to specify 'include_children' => false. See this Trac ticket for more: https://core.trac.wordpress.org/ticket/21228

| improve this answer | |
  • 6
    By the way, please excuse and alert me to any mistakes/inaccuracies :) Typing all this one-handed with a baby in the other. – helenhousandi Apr 18 '13 at 23:19
  • 1
    Where does $slug come from...? – vancoder Apr 18 '13 at 23:45
  • 1
    Just a placeholder in the code. I guess it was $term1 etc. in the original question. – helenhousandi Apr 18 '13 at 23:47
  • You are right! This method seem to work. I will give it test, and come back to vote for this answer if it is working. Thanks – ron_dev Apr 19 '13 at 3:22
  • It seem the 'taxonomy' => 'taxonomy4', // gets ignored cannot be ignored. If i put random text in this field, no result was found. Only when I assigned real taxonomy name, it give me the result. Any idea why? – ron_dev Apr 19 '13 at 9:39
1

I sugest using tax_query as the meta_query for multiple or/and operators like this

| improve this answer | |
  • Much better suggestion. As it was released some time after above answer. – FooBar Feb 12 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.