WP_Query - Сортировка результатов по значению мета-поля

4 окт. 2011 г., 18:10:50
Просмотры: 202K
Голосов: 79

Я проверил различные варианты, но пока не нашел работающего решения. У меня есть WP_Query со следующими аргументами:

$args = array(
    'post_status' => 'publish',
    'post_type' => 'listing',
    'meta_key' => 'client_feedback_score',
    'orderby' => 'client_feedback_score',
    'order' => 'DESC'
);

$query = new WP_Query($args);

Я хочу отсортировать результаты по произвольному полю записи client_feedback_score, от меньшего к большему. Но это не работает... может кто-нибудь подсказать правильное решение?

РЕДАКТИРОВАНИЕ (РЕШЕНО):

Благодаря ответу Milo, вот рабочий код для сортировки по числовому значению мета-поля:

$args = array(
    'post_status' => 'publish',
    'post_type' => 'listing',
    'meta_key' => 'client_feedback_score',
    'orderby' => 'meta_value_num',
    'order' => 'DESC'
);
0
Все ответы на вопрос 3
12
100

Параметр orderby должен быть meta_value_num или meta_value, а не именем ключа. Смотрите Параметры orderby в WP_Query.

4 окт. 2011 г. 18:25:38
Комментарии

Сработало отлично, спасибо, приятель.

Adam Moss Adam Moss
4 окт. 2011 г. 18:41:05

Спасибо! Вы мой спаситель времени! Нигде в WPCodex не упоминается про 'meta_value_num'.

BasTaller BasTaller
21 июн. 2012 г. 17:04:10

Маленькое замечание: если meta_key ещё не существует для записи, то запись будет проигнорирована.

adamj adamj
2 дек. 2015 г. 04:46:50

Является ли meta_value_num произвольным метаполем (custom post meta), которое можно назначить типам записей? Мне нужно иметь возможность редактировать это значение для каждой записи.

RobBenz RobBenz
25 апр. 2017 г. 19:50:22

@RobBenz Смотрите Произвольные поля, чтобы узнать о метаполях записей.

Milo Milo
25 апр. 2017 г. 19:52:22

Спасибо, я знаком с произвольными метаполями. Я хочу добавить метабокс к товарам WooCommerce с названием search_order или что-то подобное, чтобы при отображении результатов поиска у меня была возможность контролировать порядок их вывода. Должен ли я назвать добавляемое произвольное метаполе meta_value_num

RobBenz RobBenz
25 апр. 2017 г. 19:58:42

или meta_value_num просто берет значение того, что указано в 'meta_key' => 'search_order' для поста

RobBenz RobBenz
25 апр. 2017 г. 20:02:38

@RobBenz meta_value_num указывает WordPress сортировать результаты по числовому значению метаполя. Это не название ключа.

Milo Milo
25 апр. 2017 г. 20:09:38

как изменить meta_value_num, чтобы определенный пост "ранжировался" выше в результатах поиска

RobBenz RobBenz
25 апр. 2017 г. 21:07:50

@RobBenz Возможно, вам стоит создать новый вопрос по этой теме. Шаг 1: Назначьте любое значение вашему мета-ключу, назовём его my_meta_key, для каждой записи, чтобы сгенерировать нужный вам порядок. Шаг 2: Установите meta_key в вашем запросе как my_meta_key. Это указывает WordPress запрашивать записи, имеющие этот ключ. Шаг 3: Установите orderby в вашем запросе как meta_value_num. Это указывает WordPress не только запрашивать записи с my_meta_key, но и сортировать их численно по этому ключу. Этот аргумент запроса — единственное место, где вы увидите или используете meta_value_num.

Milo Milo
25 апр. 2017 г. 21:21:47

@adamj Есть ли какой-то обходной путь? Мне нужно отсортировать все записи, независимо от того, существует ли meta_key для записи или нет.

unbreak unbreak
22 февр. 2018 г. 09:46:45

@unbreak Простое решение — пройтись по всем записям и добавить meta_key к ним перед выполнением запроса на сортировку

adamj adamj
23 февр. 2018 г. 11:21:18
Показать остальные 7 комментариев
0
11

Если ваше мета-значение не является числовым, например, если это значение даты, то вы можете добавить параметр meta_type => DATE. Возможные значения: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'.

Запрос с указанием типа мета-поля будет выглядеть так:

$args = array(
'post_status' => 'publish',
'post_type' => 'listing',
'meta_key' => 'client_feedback_score',
'orderby' => 'meta_value_num',
'meta_type' => 'DATE',
'order' => 'DESC'
);
13 нояб. 2020 г. 00:09:13
0

Чтобы ответить на замечание @adamj в принятом ответе

если meta_key ещё не существует для записи, эта запись будет проигнорирована.

Вот решение, которое будет включать даже записи, у которых отсутствует значение client_feedback_score. Вы можете создать простой запрос для всех записей типа "listing". Затем вручную left join соединить его с таблицей postmeta, где meta_value равен client_feedback_score. После этого отсортировать с помощью условия orderby.

$args = array(
    'post_status' => 'publish',
    'post_type' => 'listing',
);

add_filter('post_clauses','post_meta_sort',10,1);
function post_meta_sort( $sql_clauses ) {
  global $wpdb;

    remove_filter( 'posts_clauses', 'post_meta_sort' ); // Остановить выполнение этой функции для других запросов.

    $sql_clauses['join'] .= "LEFT JOIN $wpdb->postmeta AS sort_score_postmeta ON $wpdb->posts.ID = sort_score_postmeta.post_id
            AND sort_score_postmeta.meta_key = 'client_feedback_score'";
    $sql_clauses['orderby'] = 'sort_score_postmeta.meta_value+0 DESC';

        return $sql_clauses;
}

$query = new WP_Query($args);
24 мая 2024 г. 19:00:49