Множественные отношения для нескольких tax_query в WP_Query

18 апр. 2013 г., 19:44:01
Просмотры: 46K
Голосов: 14

Я хочу использовать класс WP_Query() для фильтрации некоторых моих записей. Проблема, с которой я сталкиваюсь, заключается в обработке запроса таксономии. Обычно WP_Query() обрабатывает только одно отношение для tax_query() (либо AND, либо OR), но мне нужно смешанное использование этих отношений в tax_query(), как этого можно достичь?
Например:

'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'taxonomy1',
            'field' => 'slug',
            'terms' => array( $term )
        ),
        array(
            'taxonomy' => 'taxonomy3',
            'field' => 'slug',
            'terms' => array( $term3 ),
            'operator' => 'IN',
        )
       // ниже я хочу использовать отношение OR
       'relation' => 'OR',
      array(
            'taxonomy' => 'taxonomy4',
            'field' => 'slug',
            'terms' => array( $term4 )
        ),
        array(
            'taxonomy' => 'taxonomy2',
            'field' => 'slug',
            'terms' => array( $term2 ),
            'operator' => 'IN',
        )
    )  

Я знаю, что код выше не работает, нужно ли мне использовать фильтр WP_Query() для этого? Есть какие-нибудь идеи?

0
Все ответы на вопрос 2
10
17

Это можно сделать, используя term_taxonomy_id вместо слага (slug), что фактически игнорирует указанную таксономию и просто смотрит на уникальное поле term_taxonomy_id. Это позволит эффективно создать смешанное отношение. Вам нужно использовать общее отношение AND и поместить все термины, которые должны быть связаны через OR, в один элемент с использованием оператора IN. Сначала потребуется сопоставить нужные термины с их term_taxonomy_id.

$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', // игнорируется
        'field' => 'term_taxonomy_id',
        'terms' => array( $tax_map['taxonomy4'][$slug], $tax_map['taxonomy2'][$slug] ),
        'operator' => 'IN',
    ),
);

Обратите внимание, что до версии 3.5 также нужно было указывать 'include_children' => false. Подробнее см. в тикете Trac: https://core.trac.wordpress.org/ticket/21228

19 апр. 2013 г. 02:16:32
Комментарии

Кстати, прошу прощения и предупредите меня о любых ошибках/неточностях :) Печатаю всё это одной рукой, с малышом на другой.

helenhousandi helenhousandi
19 апр. 2013 г. 02:19:09

Откуда берётся $slug...?

vancoder vancoder
19 апр. 2013 г. 02:45:25

Просто заглушка в коде. Думаю, в исходном вопросе это были $term1 и т.д.

helenhousandi helenhousandi
19 апр. 2013 г. 02:47:20

Вы правы! Этот метод, кажется, работает. Я протестирую его и вернусь, чтобы проголосовать за этот ответ, если всё будет работать. Спасибо.

ron_dev ron_dev
19 апр. 2013 г. 06:22:11

Кажется, что 'taxonomy' => 'taxonomy4', // игнорируется не может быть проигнорировано. Если я ввожу случайный текст в это поле, результаты не находятся. Только когда я указываю реальное название таксономии, я получаю результат. Есть идеи, почему так?

ron_dev ron_dev
19 апр. 2013 г. 12:39:50

Вероятно, где-то в процессе происходит проверка на существование таксономии.

helenhousandi helenhousandi
19 апр. 2013 г. 17:39:55

Но, судя по тому, что я увидел в https://core.trac.wordpress.org/ticket/21228 и https://core.trac.wordpress.org/changeset/21552, проверка таксономии не должна выполняться при наличии 'term_taxonomy_id', верно?

ron_dev ron_dev
20 апр. 2013 г. 10:49:34

После множества попыток, это всё равно не работает, я думаю, что этот метод нерабочий... проверив класс WP_TAX_QUERY в https://core.trac.wordpress.org/browser/trunk/wp-includes/taxonomy.php?rev=21552, я обнаружил, что всё равно требуется проверять название таксономии перед использованием term_taxonomy_id для этой цели (поправьте, если я ошибаюсь). Таким образом, название таксономии должно присутствовать в массиве tax_query. Следовательно, этот метод не решает проблему. Есть другие предложения по её решению?

ron_dev ron_dev
23 апр. 2013 г. 07:43:41

Хорошо, я наконец оформил это (и опубликовал): http://10up.com/blog/wordpress-mixed-relationship-taxonomy-queries/ - вкратце, да, вам всё равно нужно использовать валидное название таксономии, но остальное остаётся верным.

helenhousandi helenhousandi
17 дек. 2013 г. 01:02:17

Господи, это просто нелепо, что подобного нет в документации WP. Спасибо, что написали, но если один и тот же запрос не работает для других полей так же, как для term_taxonomy_id, тогда нахрена вообще поддерживать эти поля.

jmcgrory jmcgrory
5 мар. 2022 г. 23:28:55
Показать остальные 5 комментариев
2

Я рекомендую использовать tax_query вместо meta_query для нескольких операторов or/and, как здесь

5 нояб. 2015 г. 13:00:22
Комментарии

Гораздо лучшее предложение. Так как оно было выпущено спустя некоторое время после ответа выше.

FooBar FooBar
12 февр. 2020 г. 13:04:22

Позволяет ли meta_query фильтровать по таксономии? Я не вижу, где можно указать тип таксономии

LTroya LTroya
9 авг. 2022 г. 05:56:56