2つのキーによるmeta_queryソート


8

(カスタム)投稿を2つのカスタムフィールド値でソートする必要があります...

カスタムフィールド名1:is_sponsored[値はいずれかになります10]

カスタムフィールド名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の2つの属性を取ります*

したがって、クエリに上記の引数を指定した$ 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で並べ替えることもできるように、クエリは1つの小さな違いだけで設定する必要があります。

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

[!ORDER MISSING!]プレースホルダーを見つけてください。上記は問題が正確に発生する場所を説明していると思います。


デフォルトのWP_Queryクラスでそれができるとは思いません。ドキュメントでも、「meta_valueが配列の場合、クエリを並べ替える方法を知っていますか?ここに書き込んでください」と書かれています。このためには、おそらく独自のSQLクエリを記述する必要があります。
Miha Rekar 2012年

うん、それはまだ解決されていないことは知っているが、これを整理するのに適切な場所だと思った:)
Dameer

質問に小さなプラグインを追加したので、最終的なSQLクエリの部分を表示できます。その情報で質問を編集してください。ありがとう。
カイザー2012年

ああ、これが一般的な並べ替えの仕組みに関する関連質問の情報です。
カイザー2012年

回答:


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」フィルターを使用してORDERパーツを変更します。

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();

うまくいけば、それは理にかなっています!


-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 );

うまくいくかどうか教えてください:-)


2
'meta_key'を指定しないため、これはデフォルトの(日付順)ソートになります。
Miha Rekar 2012年

@MihaRekarに感謝します。訂正してくれてありがとうございました
Md Toufiqul Islam 2012

機能しないのではないかと思います。「is_sponsored」の値が1の人を先頭にしないで、投稿を日付順にソートし続けるだけです。
Dameer、

私はこれに対する解決策を見つけることを検討しています。@MihaRekarが正しいかもしれません。このためのカスタムSQLクエリを作成する必要がある場合があります
Md Toufiqul Islam

「通常の」mySQLクエリの例を提供する方法はありますか?
Dameer、2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.