Сортировка по DESC, ASC в пользовательском WP_Query

13 авг. 2013 г., 07:55:26
Просмотры: 285K
Голосов: 10

Мне нужно выполнить многоуровневую сортировку в запросе. Проблема заключается в сортировке одного значения по DESC, а другого по ASC, как в SQL. Следующий SQL-запрос дает мне то, что я хочу, когда я запускаю его в терминале:

SELECT DISTINCT * FROM wp_posts 
INNER JOIN wp_postmeta 
ON wp_posts.ID = wp_postmeta.post_id 
WHERE wp_posts.post_type = 'post' 
AND wp_postmeta.meta_key = 'pb_issue_featured'
AND wp_posts.post_status = 'publish' 
ORDER BY wp_postmeta.meta_value DESC, wp_posts.menu_order ASC;

pb_issue_featured - это булево значение. Результат, который мне нужен - это чтобы запрос отображал записи, имеющие метазначение 1 для этого поля вверху, а все остальные - внизу. Затем вторичная сортировка должна быть по назначенному menu_order (я использую плагин post types order).

Проблема в том, что моё булево значение должно сортироваться от высокого к низкому (от 1 к 0), а menu_order наоборот. То, что сортируется первым с помощью плагина, имеет menu_order равный 1. Поэтому использование встроенного 'orderby' в WP_Query не работает. Есть ли у кого-нибудь предложения? Я рассматривал фильтр 'posts_orderby', но не смог заставить его работать. Я не был уверен, где его нужно применять или как я мог бы отладить его. Он просто не менял порядок сортировки так, как я задавал.

Спасибо за помощь! Я опубликую фактический WP_Query, если это важно, но я хотел сделать это как можно короче.

Аргументы запроса:

$args = array(
        'post_type' => 'post',
        'meta_key' => 'pb_issue_featured',
        'orderby'   => 'meta_value',
        'order' => 'DESC',
        'post_status' => 'publish',
        'posts_per_page' => $posts,
        'paged' => $paged,
        'meta_query' => array(
            array(
                'key' => 'headline',
                'value' => 1,
                'compare' => '!=' 
                )
            )
        );
$q = new WP_Query($args);
2
Комментарии

Что ж, вам следует показать WP_Query, чтобы увидеть, правильно ли он сформирован.

Marin Bînzari Marin Bînzari
13 авг. 2013 г. 08:53:28

Вот он во всей своей красе. В настоящее время я не сортирую ни по чему, кроме этого логического мета-значения, поскольку это был единственный способ заставить этот уровень сортировки работать. На сайте также используются посты с пометкой 'headline', которые имеют приоритет над постами с пометкой 'featured'. Поэтому я исключаю их в этом запросе

ian ian
13 авг. 2013 г. 09:02:58
Все ответы на вопрос 4
2
27

Попробуйте это:

$args = array(
        'post_type' => 'post',
        'meta_key' => 'pb_issue_featured',
        'orderby'   => 'meta_value',
        'order' => 'DESC',
        'posts_per_page' => $posts,
        'paged' => $paged,
        'paged' => 1,
        'meta_query' => array(
            array(
                'key' => 'headline',
                'value' => 1,
                'compare' => '!=' 
                )
            )
        );

add_filter( 'posts_orderby', 'filter_query' );
$q = new WP_Query($args);
remove_filter( 'posts_orderby', 'filter_query' );

function filter_query( $query ) {
    $query .= ', wp_posts.menu_order ASC';
    return $query;
}
13 авг. 2013 г. 09:14:05
Комментарии

Как босс, Спартакус. Спасибо за краткий и точный ответ. Это сработало идеально

ian ian
13 авг. 2013 г. 10:18:52

Вы также можете использовать массив в конструкции order by (WordPress 4.0 и новее)

GuilleOjeda GuilleOjeda
25 апр. 2017 г. 16:55:53
1

ORDER BY ID ASC

$args = array(
    'order' => 'ASC',
    'orderby' => 'ID',
);

или

ORDER BY ID DESC

$args = array(
    'order' => 'DESC',
    'orderby' => 'ID',
);
2 февр. 2021 г. 04:58:54
Комментарии

Я не думаю, что это решает исходную проблему в вопросе, которая заключалась в сортировке по двум разным свойствам в двух разных направлениях.

Rup Rup
2 февр. 2021 г. 11:21:41
1

Начиная с WordPress 4.0, благодаря изменению 29027 от 08.07.2014, стало возможным передавать массив для параметра orderby, согласно статье Более мощный ORDER BY в WordPress 4.0.

В версии 4.0 вы можете передавать массив в WP_Query в качестве значения для orderby. Синтаксис выглядит так:

$q = new WP_Query( array( 'orderby' => array( 'title' => 'DESC',
'menu_order' => 'ASC' ) ) );

Это позволяет контролировать генерацию конструкции ORDER BY с большей точностью:

ORDER BY post_title DESC, menu_order ASC

До версии 4.0 вам пришлось бы использовать сложные фильтры для SQL-запроса или конкретной конструкции. Не лучший вариант.

1 апр. 2025 г. 01:05:52
Комментарии

(Я написал этот ответ, потому что постоянно забываю это, потом нахожу этот пост на SO, а затем нахожу объявление WP.)

dossy dossy
1 апр. 2025 г. 01:06:39
2
-1

При использовании плагина Elementor и при наличии произвольного поля с именем date, добавьте следующее действие в файл elementor-pro/elementor-pro.php в редакторе плагинов.

add_action( 'elementor/query/my_custom_filter', function( $query ) {
 
    $query->set( 'meta_key', 'date' ); // установка ключа мета-данных 'date'
    $query->set( 'orderby', 'meta_value' ); // сортировка по значению мета-поля
    $query->set( 'order', 'DESC' ); // порядок сортировки по убыванию
    $query->set( 'posts_per_page', 2 ); // ограничение - 2 записи на страницу
    
} );
28 дек. 2020 г. 17:17:55
Комментарии

Как здесь связан Elementor? В вопросе автора и во всех последующих ответах или комментариях буквально нет ни одного упоминания об Elementor.

Tony Djukic Tony Djukic
30 дек. 2020 г. 02:01:14

@TonyDjukic, вы совершенно правы насчет нерелевантности Elementor. Но поскольку Google показал мне эту страницу после поиска моей конкретной ошибки о настройке WP_Query, и мне потребовалось некоторое время, чтобы найти решение, я подумал, что это может помочь кому-то еще с такой же проблемой.

Iman Iman
7 янв. 2021 г. 18:30:28