Попытка выполнить сложный пользовательский запрос поля с порядком по значению поля
У меня есть два настраиваемых поля для сообщений о событиях: event-start
и event-end
. Когда я запрашиваю текущие события, я хотел бы показать любое сообщение, в котором event-start
ИЛИ event-end
больше или равно сегодняшней дате, и я хотел бы упорядочить их по event-start
(не по умолчанию post_date).
Я создал запрос со следующими параметрами:
$args = array(
'post_type' => 'post',
'posts_per_page' => $number,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event-start',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>='
),
array(
'key' => 'event-end',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>='
)
),
'orderby' => 'meta_value',
'order' => 'ASC',
);
Запрос получает правильные сообщения, но проблема в том, что я не могу заставить orderby работать. Этот набор аргументов запускает следующий запрос:
SELECT SQL_CALC_FOUND_ROWS wp_18_posts.ID FROM wp_18_posts INNER JOIN wp_18_postmeta ON (wp_18_posts.ID = wp_18_postmeta.post_id)
INNER JOIN wp_18_postmeta AS mt1 ON (wp_18_posts.ID = mt1.post_id) WHERE 1=1 AND wp_18_posts.post_type = 'post' AND (wp_18_posts.post_status = 'publish' OR wp_18_posts.post_status = 'private') AND ( (wp_18_postmeta.meta_key = 'event-start' AND CAST(wp_18_postmeta.meta_value AS SIGNED) >= '1344289896')
OR (mt1.meta_key = 'event-end' AND CAST(mt1.meta_value AS SIGNED) >= '1344289896') ) GROUP BY wp_18_posts.ID **ORDER BY wp_18_posts.post_date** ASC LIMIT 0, 3
Обратите внимание, что предложение ORDER BY по-прежнему имеет значение post_date. Если я изменю аргументы запроса, чтобы использовать старый стиль meta_key, а также упорядочить meta_value вместе с новым стилем meta_query следующим образом:
$args = array(
'post_type' => 'post',
'posts_per_page' => $number,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event-start',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>='
),
array(
'key' => 'event-end',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>='
)
),
'orderby' => 'meta_value',
'meta_key' => 'event-start',
'order' => 'ASC',
);
В итоге я получаю следующий запрос:
SELECT SQL_CALC_FOUND_ROWS wp_18_posts.ID FROM wp_18_posts INNER JOIN wp_18_postmeta ON (wp_18_posts.ID = wp_18_postmeta.post_id)
INNER JOIN wp_18_postmeta AS mt1 ON (wp_18_posts.ID = mt1.post_id)
INNER JOIN wp_18_postmeta AS mt2 ON (wp_18_posts.ID = mt2.post_id) WHERE 1=1 AND wp_18_posts.post_type = 'post' AND (wp_18_posts.post_status = 'publish' OR wp_18_posts.post_status = 'private') AND (wp_18_postmeta.meta_key = 'event-start'
OR (mt1.meta_key = 'event-start' AND CAST(mt1.meta_value AS SIGNED) >= '1344289518')
OR (mt2.meta_key = 'event-end' AND CAST(mt2.meta_value AS SIGNED) >= '1344289518') ) GROUP BY wp_18_posts.ID ORDER BY wp_18_postmeta.meta_value ASC LIMIT 0, 3
, который извлекает все сообщения с мета-ключом event-start
независимо от даты, установленной для этого ключа.
Любые идеи о том, как настроить сложный пользовательский запрос поля и упорядочить значение event-start
, были бы замечательными ценится.
2 answers
Если значение ваших пользовательских полей числовое, вы можете попробовать сделать заказ с помощью meta_value_num. Также обратите внимание, что как meta_value, так и meta_value_num требуют meta_key в запросе, как описано здесь.
$args = array(
'post_type' => 'post',
'posts_per_page' => $number,
'meta_query' => array(
'relation' => 'OR',
array(
'meta_key' => 'event-start',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>='
),
array(
'meta_key' => 'event-end',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>='
)
),
'orderby' => 'meta_value_num',
'order' => 'ASC',
);
Вот лучшее решение, которое я нашел:
$args = array(
'post_type' => 'post',
'posts_per_page' => $number,
'meta_key' => 'event-start',
'meta_value' => $today_is,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event-start',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>=',
),
array(
'key' => 'event-end',
'value' => $today_is,
'type' => 'NUMERIC',
'compare' => '>=',
)
),
'orderby' => 'meta_value',
'order' => 'ASC',
);
Он использует тот же комплекс meta_query
, но я добавил отдельные meta_key
и meta_value
, чтобы вызвать meta_value
порядок.
Если я правильно помню, в то время, когда я писал этот пост, я пробовал это решение, но оно не сработало. Я также считаю, что наткнулся на билет Trac в ядре WordPress, связанный с этой проблемой, но ни за что на свете не могу его сейчас найти.
Итог: во время первоначального сообщения, я думаю, что был Ошибка WordPress, которая помешала этому работать, но сейчас она работает.