сортировка мета-запросов по 2 ключам

8

Мне нужно сортировать (пользовательские) сообщения по 2 значениям настраиваемых полей ...

Имя настраиваемого поля 1: is_sponsored[значение может быть 1или 0]

Имя настраиваемого поля 2: sfp_date[ timestampтекущая дата публикации в секундах]

Посты, у которых is_sponsoredзначение " " равно 1, должны быть сверху, отсортированы по " sfp_date" в DESCконечном порядке. Все остальные сообщения, чье is_sponsoredзначение " " равно 0, должны быть перечислены ниже - также в порядке убывания (" sfp_date").

У меня есть что-то вроде:

$sfp_query_args = array(
    'tax_query'   => array( 
        array( 
            'taxonomy' => 'sfp_posts',
            'terms'    => array( 1, 5, 8 )
        )
    ),
    'post_type'   => 'sfpposts',
    'post_status' => 'publish',
    'showposts'   => 15,
    'paged'       => $paged,
    'meta_key'    => 'sfp_date', 
    'orderby'     => 'meta_value_num', 
    'order'       => 'DESC', 
    'meta_query'  => array(
        'key'          => 'is_sponsored',
        'value'        => 2,
        'type'         => 'NUMERIC',
        'compare'      => '<='
    )
);
$wp_q = new WP_Query( $sfp_query_args );

... но не работает. Любые идеи?


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

<?php
/** Plugin Name: (#67600) Dump Query parts */
function wpse67600_dump_query_parts( $pieces )
{
    echo '<pre>'.var_export( $pieces, true ).'</pre>';
    return $pieces;
}
add_filter( 'posts_clauses', 'wpse67600_dump_query_parts' );

OP ПОЖАЛУЙСТА, ДОБАВЬТЕ ВЫХОД ПЛАГИНА ЗДЕСЬ - используйте ссылку "изменить" .

РЕДАКТИРОВАТЬ Dameer

Хорошо, после отслеживания запроса и многочисленных обходных путей, я пришел к следующему ...

Если я немного упросту «$ sfp_query_args», результат будет близок к тому, что требуется, однако невозможность сортировки сообщений останется как есть. Вот:

$sfp_query_args1 = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => (int)$per_page,
    'paged' => $paged,
    'meta_key' => 'is_sponsored', 
    'orderby' => 'meta_value date'
);
  • * orderby принимает два атрибута: meta_value и date *

Таким образом, $ wpdb-> request с указанными выше аргументами в запросе выглядит так:

SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID 
FROM $wpdb->posts 
INNER JOIN $wpdb->term_relationships 
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) 
INNER JOIN $wpdb->postmeta 
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) 
WHERE 1=1 
AND $wpdb->posts.post_type = 'sfpposts' 
AND ($wpdb->posts.post_status = 'publish') 
AND ($wpdb->postmeta.meta_key = 'is_sponsored' ) 
GROUP BY $wpdb->posts.ID 
ORDER BY $wpdb->postmeta.meta_value, $wpdb->posts.post_date DESC 
LIMIT 0, $per_page

И, наконец, для того, чтобы можно было также сортировать по meta_value, запрос должен быть установлен только с одним небольшим отличием:

SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID 
FROM $wpdb->posts 
INNER JOIN $wpdb->term_relationships 
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) 
INNER JOIN $wpdb->postmeta 
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) 
WHERE 1=1 
AND $wpdb->posts.post_type = 'sfpposts' 
AND ($wpdb->posts.post_status = 'publish') 
AND ($wpdb->postmeta.meta_key = 'is_sponsored' ) 
GROUP BY $wpdb->posts.ID 
ORDER BY $wpdb->postmeta.meta_value [!ORDER MISSING!], $wpdb->posts.post_date DESC 
LIMIT 0, $per_page

Пожалуйста, укажите [! ЗАКАЗАТЬ ПРОПУСТИТЬ!] Заполнитель. Я думаю, что выше должно объяснить, где именно проблема возникает.

Dameer
источник
Я не верю, что вы можете сделать это с классом WP_Query по умолчанию. Даже в документах написано «Знаете ли вы, как отсортировать запрос, если meta_value является массивом? Напишите здесь». Вам, вероятно, придется написать собственный SQL-запрос для этого.
Миха Рекар
Да, я знаю, что это еще не решено, но я думал, что это правильное место, чтобы разобраться с этим :)
Dameer
Я добавил небольшой плагин к вашему вопросу, чтобы вы могли показать нам окончательные части SQL-запроса. Пожалуйста, измените ваш вопрос с этой информацией. Спасибо.
Кайзер
Ох, и вот некоторая информация из смежного вопроса о том, как сортировка работает в целом.
Кайзер

Ответы:

2

ОК, последний обходной путь будет разделить запрос:

$sfp_query_args = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
    'meta_key' => 'is_sponsored',
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => (int)$per_page,
    'paged' => $paged
);

... и использовать фильтр "posts_orderby", чтобы изменить часть ЗАКАЗА:

add_filter( 'posts_orderby', 'sfp_modify_orderby' );
function sfp_modify_orderby( $orderby ) {
    if( !is_admin() && is_tax( 'sfp_post_category' ) ) {
        global $wpdb;
        $orderby = " $wpdb->postmeta.meta_value DESC, $wpdb->posts.post_date DESC ";
    }
    return $orderby;
}

Скорее всего, вам нужно будет удалить фильтр после цикла на странице, чтобы «posts_orderby» не влиял на любой другой запрос (боковая панель или нижний колонтитул). Итак, вот еще одна функция для добавления в «functions.php»:

function sfp_remove_orderby_filter() {
    remove_filter( 'posts_orderby', 'sfp_modify_orderby' );
}

... и на странице, используя наш фильтр сброса запросов:

if( have_posts() ) : while( have_posts() ) : the_post();
    // code
endwhile;
else :
    // code
endif;

sfp_remove_orderby_filter();

Надеюсь, это имеет смысл!

Dameer
источник
-1

Я пишу ваш запрос немного изменив. Я надеюсь, что это может помочь.

$sfp_query_args = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_posts', 'terms' => array( 1, 5, 8) ) ),
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => 15,
    'paged' => $paged, 
    'meta_key'=>'sfp_date', 
    'meta_query' => array(
    array(
        'key' => 'sfp_date',
            'type' => 'NUMERIC',
    ),
    array(
        'key' => 'is_sponsored',
        'value' => '2',
        'compare' => '<='
    )       
    ),
    'orderby' => 'meta_value_num', 
    'order' => 'DESC',
);
$wp_q = new WP_Query( $sfp_query_args );

Пожалуйста, дайте мне знать, работает это или нет :-)

Md Toufiqul Islam
источник
2
Это будет сортировка по умолчанию (по дате), так как вы не предоставляете 'meta_key'.
Миха Рекар
Спасибо @MihaRekar, Это была ошибка, спасибо за ваше исправление
Md Toufiqul Islam
Боюсь, это не сработает, а просто продолжает сортировать сообщения по дате, не ставя тех, у кого значение is_sponsored равно 1, на верх.
Дамер
Я ищу решение этой проблемы. Может быть @MihaRekar прав. Возможно, вам придется написать собственный SQL-запрос для этого
Md Toufiqul Islam
Есть ли способ, которым вы можете привести пример «нормального» запроса MySQL?
Дамер