Попытка выполнить сложный пользовательский запрос поля с порядком по значению поля


У меня есть два настраиваемых поля для сообщений о событиях: 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, были бы замечательными ценится.

Author: DaveE, 2012-08-06

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',
);
 1
Author: unifiedac, 2014-04-25 20:04:14

Вот лучшее решение, которое я нашел:

$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, которая помешала этому работать, но сейчас она работает.

 1
Author: DaveE, 2014-04-28 16:20:22