web-dev-qa-db-ja.com

Meta_value_numを使用するとき、複数のmeta_keysで並べることは可能ですか?

order&orderbyのドキュメント を読んでみると、複数のmeta_key値に基づく注文のサポートがあるかどうかは私には明らかではありません。

明らかに、meta_queryを使用して、複数のキーと値のペアに基づいて投稿を返すことができますが、これらの結果が複数のmeta_keysに基づいて返される順序を制御できるようにしたいです。

たとえば、複数のカテゴリがあり、各カテゴリにランクがあるページがあります。ユーザーが3つの異なるカテゴリのいずれかにあるページを検索している場合は、必要な投稿すべてを次のように返します。

$query = array(
  'order' => 'DESC',
  'orderby' => 'meta_value_num',
  'meta_query' => array(
    'relation' => 'OR',
    array( 'key' => 'cat1', 'type' => 'numeric' ),
    array( 'key' => 'cat2', 'type' => 'numeric' ),
    array( 'key' => 'cat3', 'type' => 'numeric' )
  );
);

ただし、それらが返されたら、結果が返されたカテゴリのいずれか1つにわたる最も高い数値に基づいてそれらが順序付けられるようにします。つまり、9の値がcat1の投稿は、9の値がcat3の投稿とほぼ同じ順序で表示されます。

この答えを見てmeta_key'orderby' => 'meta_value_num'には必要ないと思われますが、それはmeta_valueのドキュメントとは一致しません。 meta_value_num...より明確に説明されています。ありがとうございます。

4
Dan

'orderby'と 'meta_query'についてのWP 4.2のクエリの改善点を確認してください。詳細は https://make.wordpress.org/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query .

Meta_query句に名前を付けて、順番に並べるようにしてください。

次のコードはテストされていません。

$query = array(
  'order' => 'DESC',
  'meta_query' => array(
    'relation' => 'OR',
    'cat1-clause' => array( 'key' => 'cat1', 'type' => 'numeric' ),
    'cat2-clause' => array( 'key' => 'cat2', 'type' => 'numeric' ),
    'cat3-clause' => array( 'key' => 'cat3', 'type' => 'numeric' )
  );
  'orderby' => array(
    'cat1-clause' => 'ASC',
    'cat2-clause' => 'ASC',
    'cat3-clause' => 'ASC',
  ),
);
1
Pim Schaaf

WP_Queryのget_postsメソッドを見ると、posts_requestフィルタに渡された変数を出力することでSQLをデバッグするのは簡単です。

// Debug the WP_Query sql
add_filter( 'posts_request', function( $sql ) {
  echo "<pre>";
  var_dump( $sql );
  echo "</pre>";
  return $sql;
} );

結果は次のようになります。

string(426) "SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND (
  wp_postmeta.meta_key = 'cat1'
  OR
  wp_postmeta.meta_key = 'cat2'
  OR
  wp_postmeta.meta_key = 'cat3'
) GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value+0 DESC LIMIT 0, 10"

クエリは最初は正しく見えるかもしれませんが、そうではありません。 meta_value句には、内部結合の最初の行からORDER BYを使用します。この場合、それは'cat1'です。この振る舞いを変更するには、posts_orderbyフックを使用してORDER BYステートメントを変更し、MAX mysql関数を使用して、最初の行だけでなくすべてのmeta_valuesの最大値を使用するようにします。

// Filter to alter the orderby sql
function nvdGMCWh_alter_posts_orderby( $sql ) {
  return "MAX( $wpdb->postmeta.meta_value+0 ) DESC";
} // - alter_posts_orderby
// Register the filter
add_filter( 'posts_orderby', 'nvdGMCWh_alter_posts_orderby' );

// The WP_Query
$res = new WP_Query;
$args = [
  'order' => 'DESC',
  'orderby' => 'meta_value_num',
  'meta_query' => [
    'relation' => 'OR',
    ['key' => 'cat1', 'type' => 'numeric'],
    ['key' => 'cat2', 'type' => 'numeric'],
    ['key' => 'cat3', 'type' => 'numeric'],
  ],
]; // - $args
// Execute the query and get the results
$result = $res->query( $args );
// Clean up the filter so it won't affect later queries
remove_filter( 'posts_orderby', 'nvdGMCWh_alter_posts_orderby' );
// Loop through the results
foreach ( $result as $post ) {
  // ... code here
} // - foreach
0
forsvunnet