WordPress で投稿やカスタム投稿タイプを並べ替えるとき、デフォルトでは「日付」「タイトル」「ランダム順」などが一般的です。しかし、カスタムフィールド(メタ情報)を含めた複数の条件でソートしたい場合もあります。たとえば「独自の数値や順位をもとに昇順で並べ、そのあとに投稿日を降順に並べる」など、より柔軟な並び替えが必要なシーンもあるはずです。
本記事では、WordPress でカスタムフィールドを使った複数の条件によるソート方法について解説します。
カスタムフィールドを使った複数ソートが必要なシーン
独自の並び順をつけたい時
管理画面やフロントエンドで、独自の優先度や数値をカスタムフィールドに保存し、その値を元に並べ替えたいケース。
複数のメタ情報と標準のタイトルや日付を組み合わせたい時
例:優先度(昇順)→ タイトル(昇順) → 日付(降順)というように、複雑な条件で並べ替える要望があるケース。
「標準のソートではできない柔軟な条件付けをしたい」── そんな時に、カスタムフィールドでの複数ソートが役立ちます。
基本のソート構文:WP_Query での orderby 配列指定
WordPress 4.0 以降は orderby に配列を設定できるので、下記のように複数の条件を連続して指定できます。カスタムフィールド(数値扱い)をまず昇順に並べ、そのあとに日付を降順で並べる例です。
$args = [
'post_type' => 'post',
'posts_per_page' => -1,
'meta_key' => 'my_custom_key',
'orderby' => [
'meta_value_num' => 'ASC',
'date' => 'DESC',
],
];
$query = new WP_Query( $args );
- meta_key でソートしたいキー名を指定し、数値の場合は meta_value_num、文字列の場合は meta_value を使い分ける。
- orderby は配列で渡すことで、第一優先→第二優先といった複数条件ソートが可能になる。
カスタムフィールドが複数ある場合
複数のカスタムフィールドを使いたい場合は、次のように meta_query でキーを指定し、それぞれをソート条件に含める必要があります。
$args = [
'post_type' => 'post',
'posts_per_page' => -1,
'meta_query' => [
'relation' => 'AND',
[
'key' => 'custom_field_a',
'type' => 'NUMERIC',
'compare' => 'EXISTS',
],
[
'key' => 'custom_field_b',
'type' => 'NUMERIC',
'compare' => 'EXISTS',
],
],
'orderby' => [
'custom_field_a' => 'ASC', // 節に名前が無いため紐付かない
'custom_field_b' => 'DESC',
],
];
$query = new WP_Query( $args );
複数のメタキーを条件にソートするには、
meta_queryの各節に明示的な名前(配列キー)を付け、orderby側で同じ名前を参照する必要があります。メタキーの値(custom_field_aなど)をそのままorderbyのキーにしても、どの節に対応するか紐付かず、複数条件ソートが機能しません。$args = [
'post_type' => 'post',
'posts_per_page' => -1,
'meta_query' => [
'relation' => 'AND',
'field_a' => [ // 節に明示的な名前(エイリアス)を付ける
'key' => 'custom_field_a',
'type' => 'NUMERIC',
'compare' => 'EXISTS',
],
'field_b' => [
'key' => 'custom_field_b',
'type' => 'NUMERIC',
'compare' => 'EXISTS',
],
],
'orderby' => [
'field_a' => 'ASC', // 第一優先(meta_queryの節名を参照)
'field_b' => 'DESC', // 第二優先
],
];
$query = new WP_Query( $args );
- type をしっかり指定しないと、正しい並び替えが期待できない場合がある(数字が文字列ソートされるなど)。
- relation を AND にすることで、両方のフィールドが存在する投稿だけに限定できる。
テキストフィールドと数値フィールドを混在させたい場合
異なるタイプのカスタムフィールドを使う場合も、基本は同様です。たとえば「テキスト(文字列)をアルファベット順に並べた上で、数値フィールドを昇順に並べる」なら、下記のように設定します。
$args = [
'post_type' => 'post',
'posts_per_page' => -1,
'meta_query' => [
'relation' => 'AND',
'text_clause' => [
'key' => 'custom_text',
'compare' => 'EXISTS',
'type' => 'CHAR', // 文字列として扱う
],
'number_clause' => [
'key' => 'custom_number',
'compare' => 'EXISTS',
'type' => 'NUMERIC' // 数値として扱う
],
],
'orderby' => [
'text_clause' => 'ASC',
'number_clause' => 'ASC',
],
];
$query = new WP_Query( $args );
pre_get_posts フィルタを使って管理画面やアーカイブをカスタマイズ
pre_get_posts フィルタを使うと、管理画面やアーカイブページなど既存のクエリに対してソート条件を変更できます。たとえば、管理画面で特定の投稿タイプだけカスタムフィールドを優先してソートしたい場合は下記のように書きます。
function my_admin_sort_posts_by_custom_field( $query ) {
if ( is_admin() && $query->is_main_query() ) {
if ( 'my_post_type' === $query->get( 'post_type' ) ) {
// カスタムフィールド優先
$query->set( 'meta_key', 'order_key' );
$query->set( 'orderby', [
'meta_value_num' => 'ASC',
'title' => 'ASC',
] );
}
}
}
add_action( 'pre_get_posts', 'my_admin_sort_posts_by_custom_field' );
管理画面での絞り込みやカスタム投稿タイプの一覧画面など、既存の画面を柔軟にカスタマイズしたい時に便利です。
複雑なソートを成功させるポイント
meta_query と type の指定を忘れない
特に複数のカスタムフィールドを扱う場合は、meta_query の指定でデータベースに読み込むようにしておく必要があります。また、文字列なら CHAR、数値なら NUMERIC と適切に指定することが重要です。
パフォーマンスを考慮する
meta_query の数が増えると JOIN が増え、クエリが複雑になります。多量の投稿を扱うサイトではパフォーマンスに影響が出る場合があるため、専用のテーブルを用意するなどの検討が必要です。
特定の値を優先して表示するソート
カスタムフィールドが特定の値(例: custom_field_a = 'important')を持つ投稿を先頭に表示し、それ以外の投稿もその後に続けて表示したい場合があります。
post__inは指定したIDの投稿だけを返すフィルターです。優先表示させたい投稿のIDだけをpost__inに渡すと、それ以外の投稿は結果から除外されてしまいます。「優先表示+残りの投稿も表示」を実現するには、全投稿のID配列を用意したうえで、優先させたいIDを先頭に並べ替えてからpost__inに渡す必要があります。// 通常の並び順で全投稿IDを取得
$all_ids = get_posts(array(
'post_type' => 'post',
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
'fields' => 'ids',
));
// 優先表示したい投稿のIDを取得(custom_field_a = 'important')
$important_query = new WP_Query(array(
'post_type' => 'post',
'posts_per_page' => -1,
'meta_key' => 'custom_field_a',
'meta_value' => 'important',
'fields' => 'ids',
));
$important_ids = $important_query->posts;
// 優先ID + 残りのID(重複除外)で、完全な並び順を作る
$other_ids = array_diff($all_ids, $important_ids);
$ordered_ids = array_merge($important_ids, $other_ids);
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'post__in' => $ordered_ids,
'orderby' => 'post__in', // $ordered_idsの並び順をそのまま使う
);
$query = new WP_Query($args);
これにより、custom_field_aの値がimportantの投稿が先頭に表示され、それ以外の投稿もその後に続けて表示されます。post__inに渡すID数が非常に多いサイトでは、クエリの負荷が増える点に留意してください。
関連記事
よくある質問(FAQ)
まとめ
WordPress でカスタムフィールドを含む複数の条件でソートを行う方法は、以下のステップが基本です。
- 単一ソート なら meta_key と orderby に meta_value or meta_value_num を設定。
- 複数ソート するなら、meta_query の各節に名前(エイリアス)を付け、orderby で同じ名前を参照する。
- 管理画面など既存クエリ をカスタマイズしたい時は pre_get_posts を活用。
こうした設定を組み合わせることで、柔軟なソートを実現できます。並び順はユーザーの使い勝手や運用効率にも大きく影響するため、ぜひ自分のサイトの要件に合わせて最適なソートロジックを組んでみてください。
