Пользовательский запрос с сортировкой по meta_value произвольного поля
Как известно, начиная с WP3.0 появились возможности для расширенных пользовательских запросов, что замечательно. В связи с этим некоторые параметры запросов для произвольных полей, такие как meta_key, meta_value, были объявлены устаревшими в пользу нового параметра meta_query (смотрите здесь)
Я пытаюсь создать довольно простой запрос с новым синтаксисом, запрашивая записи определенного типа (services), которые содержат указанный meta_key (order_in_archive) - это работает как ожидалось. Но - я хочу отсортировать результаты запроса по meta_value, и это не получается.
Вот мой запрос -
query_posts(
array( 'post_type' => 'services',
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_query' => array(
array('key' => 'order_in_archive'))
)
);
Я пробовал сортировать также по meta_value_numeric и meta_value, но в любом случае результаты сортируются по дате публикации (как обычные записи). Кто-нибудь знает, как это можно сделать?
Спасибо

Вы можете определить мета-ключ для параметра orderby с использованием старого метода (я тестировал на WP 3.1.1)...
query_posts(
array( 'post_type' => 'services',
'order' => 'ASC',
'meta_key' => 'some_key',
'orderby' => 'meta_value', //или 'meta_value_num'
'meta_query' => array(
array('key' => 'order_in_archive',
'value' => 'some_value'
)
)
)
);

Эта проблема в целом решена начиная с WordPress 4.2 благодаря использованию именованных запросов. Например:
$args = array(
'post_type' => 'services',
'orderby' => 'order_clause',
'meta_query' => array(
'order_clause' => array(
'key' => 'order_in_archive',
'value' => 'some_value',
'type' => 'NUMERIC' // если поле не является числовым
)));
В моём случае мне нужно было сортировать по числовому полю, и пришлось использовать 'type' => 'NUMERIC'
внутри meta_query.

WP Codex действительно вводит в заблуждение при рассмотрении этой проблемы.
Вам на самом деле не нужен параметр meta_query для использования orderby, вместо этого используется параметр meta_key, который, хотя согласно WP Codex устарел, было установлено здесь: Как использовать orderby с meta_query в Wordpress 3.1? что orderby все еще требует meta_key.
Поэтому должно быть так:
query_posts( array(
'post_type' => 'services',
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_key' => 'order_in_archive'
) )

Ну да, это старый метод выполнения такого запроса, и он, похоже, работает для данного конкретного случая. Однако для более сложных запросов он не подойдет. Я выяснил, что это известная проблема, над которой ведется работа, подробности можно найти в тикетах trac #15031 и #17065

Это просто:
Вот мой код:
query_posts(array(
'post_type' => 'directors',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'director_weight',
'meta_key' => 'director_weight'
) );
Главная деталь: обязательно включите параметр meta_key
, мой код не сортировал записи, пока я не добавил meta_key
, и вот как это выглядит:
Полный код для вывода списка изображений directors
, отсортированных по полю director_weight
:
<?php
query_posts(array(
'post_type' => 'directors',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'director_weight',
'meta_key' => 'director_weight'
) );
while (have_posts()) : the_post();
?>
<li <?php echo get_field('director_weight') ?>>
<img src="<?php echo get_field('director_imagen') ?>">
</li>
<?php
endwhile;
wp_reset_query();
?>

Не используйте query_posts.
$meta_query = new WP_Meta_Query( $meta_query_args );
$meta_query_args = array(
'post_type' => 'services', // Тип записи
'order' => 'ASC', // Порядок сортировки (по возрастанию)
'meta_key' => 'your_key', // Мета-ключ
'orderby' => 'meta_value', //или 'meta_value_num' - сортировка по мета-значению или числовому мета-значению
'meta_query' => array(
array('key' => 'order_in_archive', // Ключ для мета-запроса
'value' => 'some_value' // Значение для сравнения
)));
Используйте параметры WP_Meta_Query

Мне нужно было отсортировать набор пользовательских дат событий по убыванию. Поскольку мои пользовательские даты событий хранились в таблице wp_postmeta и обычно отличались от post_date или modified, мне подошло следующее решение:
$args = array(
'post_type' => 'events', // мой тип записи - у вас может быть 'posts'
'post_status' => 'publish', // получать только записи с этим статусом
'orderby' => 'meta_value', // сортировать по значению meta_value следующего meta_key
'meta_key' => 'my_custom_eventdate', // название пользовательского meta_key
'order'=> 'DESC' // сортировка по убыванию
);
$posts = new WP_Query($args);
Затем можно пройтись по $posts следующим образом:
foreach($posts->posts as $p){
$post_id = $p->ID;
// и так далее...
// # пример получения моей даты события
$event = get_post_meta($post_id, 'my_custom_eventdate', true);
}

Следующее решение работает:
$args = array(
'post_type' => 'services',
'order' => 'ASC',
'orderby' => 'order_clause',
'meta_query' => array(
'order_clause' => array(
'key' => 'order_in_archive'
)
)
);
Необходимо было указать ключ подмассива meta_query order_clause
для значения orderby
.

Вопрос касается относительно нового параметра meta_query
и настройки orderby
для работы с ним, а не о более старых, но всё ещё рабочих параметрах meta_key
/meta_value
. Также давайте не поощрять использование query_posts
.
