本文へ移動

トラブルシュート

WP_Queryのmeta_queryが効かない時のチェックリスト

meta_queryを書いても0件になる、対象外まで出る時は、まず対象投稿にメタキーと値が本当に保存されているか確認します。管理画面またはget_post_meta()で実データを見た後、条件を1つに減らし、compare、type、relationを戻します。

Huddly Huddly 投稿日: 2026年9月1日 読了目安: 6分

0件ならkeyとvalueを先に確認する

対象投稿を1件決め、管理画面またはget_post_meta()で、meta_querykeyvalueが実際に保存されているか確認します。未保存と空文字はmetadata_exists()で切り分けます。保存された値が合っていれば条件を1つに減らし、comparetypevalueの形、relationを順に戻します。

画面の表示名ではなく、保存されているキーと値を確認してください。

0件・出すぎる・数値や日付が合わない症状を分ける

エラーが出なくても、投稿が0件になる、対象外まで出る、数値や日付だけ合わない、という形で問題が現れます。症状を次の表へ当てはめてください。

症状最初に疑う場所よくある原因
投稿が1件も出ないkey / value / post_type保存されているメタキー名や値が想定と違う
出るはずの投稿だけ漏れるcompare / type数値や日付を文字列として比較している
出てほしくない投稿まで出るrelation / compareAND と OR、IN と LIKE の使い分けが違う
BETWEEN が効かないvalue の形 / type配列ではない、または保存形式と比較形式が違う
ACFの値で絞れない保存されている値画面上の表示形式と実際に保存されている値が違う

meta_queryの配列の形そのものが分からない場合はmeta_queryの基本構造へ戻ります。ACF固有の値が関係する時は、ACFの値が検索できない時の確認ポイントも、実際に保存されている値を見ながら確認してください。

まず疑う順番

  1. 1
    対象投稿にメタキーと値が本当に保存されているか確認する
  2. 2
    post_type と posts_per_page だけの最小クエリで投稿が出るか確認する
  3. 3
    meta_query を1条件だけに減らす
  4. 4
    compare と value の形が合っているか確認する
  5. 5
    数値や日付なら type を確認する
  6. 6
    複数条件なら relation を最後に確認する

meta_queryの条件を1つずつ確認する

原因候補を整理したら、実際に保存されている値、最小クエリ、比較方法、型、複数条件、ほかの引数の順に確認します。

1. 保存されている key と value を確認する

meta_query では、管理画面に表示されている項目名ではなく、保存されているメタキー名を指定します。たとえば画面上では「価格」と表示されていても、実際のキーが priceproduct_price_price のどれなのかは別問題です。

また、保存されている値は、画面の見た目と一致するとは限りません。チェックボックス、セレクト、日付フィールド、プラグインが作るフィールドでは、表示上の文字と保存される値が違うことがあります。まず対象投稿1件で、保存されている key と value を確認します。

商品投稿に保存されたpriceメタキーと値を確認している画面
保存内容を確認画面のラベルではなくkeyとvalueを見る

meta_queryのkeyにprice、valueに実際に保存されている値を指定できるか確認します。

コードで確認する場合は、まず対象投稿のIDを1つ決めて、その投稿に保存されている値を見ます。これは原因切り分け用なので、公開画面にそのまま出す前提ではなく、検証環境で一時的に使う確認コードとして扱います。

原因を切り分けるための一時的な確認コードです。ローカルなどの検証環境だけで使い、確認後は削除してください。

PHPdebug-meta.php対象投稿に保存されているカスタムフィールド値を確認する最小例
$post_id = 123;$meta_key = 'price'; var_dump( metadata_exists( 'post', $post_id, $meta_key ) );var_dump( get_post_meta( $post_id, $meta_key, true ) );var_dump( get_post_meta( $post_id, $meta_key, false ) );

このコードを確認したいテンプレートへ一時的に置くと、var_dump()の結果はそのページのコードを置いた位置に表示されます。公開画面には残さず、ローカルまたは検証環境でだけ使ってください。画面へ出せない環境では、error_log()とWordPressのデバッグログを使う方法へ切り替えます。

metadata_exists()でキー自体の有無を確認し、get_post_meta()で値を確認します。単一値を返す第3引数trueだけでは、未保存と「空文字を保存済み」を見分けにくい場合があります。同じキーが複数回保存される設計なら、第3引数falseの配列も見て、どの値を条件にするか決めてください。

2. meta_query を外した最小クエリで確認する

次に、meta_query 以外の条件で投稿が取れるかを確認します。たとえば post_type が間違っている、公開済みではない、カスタム投稿タイプ名が違う、といった問題があると、meta_query をいくら直しても投稿は出ません。

最初は、対象の投稿タイプから1件だけ返すコードにします。ここで投稿が出ないなら、原因は meta_query ではなく、投稿タイプや投稿ステータスなど別の条件にあります。

原因を切り分けるための一時的な確認コードです。ローカルなどの検証環境だけで使い、確認後は削除してください。

PHPminimum-query.phpmeta_query を外して投稿タイプだけで1件取得できるか確認する
$args = [   'post_type'      => 'product',   'posts_per_page' => 1,]; $test_query = new WP_Query( $args ); if ( $test_query->have_posts() ) {   while ( $test_query->have_posts() ) {      $test_query->the_post();      echo esc_html( get_the_title() );   }} wp_reset_postdata();

このコードのポイントは、あえて条件を少なくしていることです。meta_query、並び順、タクソノミー条件、検索条件を一度外し、投稿タイプだけで取れるかを確認します。ここを飛ばすと、meta_queryが原因ではないのにmeta_queryだけを直し続けてしまいます。

3. meta_query は1条件だけに減らして試す

投稿タイプだけで投稿が出ることを確認できたら、次は meta_query を1条件だけ追加します。複数条件を一気に書くと、どの条件が投稿を除外しているのか分からなくなります。

まずは「この値を持つ投稿が1件以上ある」と分かっているキーと値で試します。存在が確認できているデータを使うことで、構文の問題なのか、値の問題なのかを分けやすくなります。

原因を切り分けるための一時的な確認コードです。ローカルなどの検証環境だけで使い、確認後は削除してください。

PHPsingle-meta-query.phpmeta_query を1条件だけにして切り分ける最小例
$args = [   'post_type'      => 'product',   'posts_per_page' => 5,   'meta_query'     => [      [         'key'     => 'color',         'value'   => 'blue',         'compare' => '=',      ],   ],]; $products = new WP_Query( $args );

このコードのポイントは、meta_queryが「配列の中に条件配列を入れる形」になっている点です。条件が1つだけでも、meta_queryは入れ子の配列として書きます。ここを崩すと、意図した条件として解釈されません。

LIKEINBETWEENへ進む前に、まず=で保存値と完全一致するかを確認します。

4. compare と value の形が合っているか確認する

compare は、value をどう比較するかを指定します。= なら単一の値との一致、IN なら複数候補のいずれか、BETWEEN なら範囲指定、EXISTS ならキーの存在確認というように、比較の意味が変わります。

ここでよくあるのは、INBETWEEN を使っているのに value が配列になっていないパターンです。逆に、完全一致でよいのに LIKE を使ってしまい、想定より広くヒットすることもあります。

使いたい条件comparevalue の形
値が完全一致する投稿だけ出したい='blue' のような単一値
複数候補のどれかに一致させたいINarray( 'blue', 'red' ) のような配列
範囲内の値に絞りたいBETWEENarray( 1000, 3000 ) のような2要素の配列
指定キーが存在する投稿を出したいEXISTS通常は value を指定しない
指定キーが存在しない投稿を出したいNOT EXISTS通常は value を指定しない

value の形が合っていないと、コードの見た目は近くても結果が変わります。とくに BETWEEN は、下限と上限を配列で渡す必要があるため、単一値を入れていないか確認してください。

5. 数値や日付は type を確認する

カスタムフィールドの値は、基本的に文字列として保存され、meta_querytypeを省略した比較型もCHARです。そのため、価格、点数、在庫数のような数値を文字列のまま比較すると、期待と違う結果になることがあります。

たとえば数値として 100 より大きいものを取りたい場合、type を指定しないままだと、意図した数値比較にならないことがあります。数値なら NUMERIC、日付なら保存形式に合った DATE や、日付文字列として比較できる形式を検討します。

クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。

PHPnumeric-meta-query.php価格を数値として比較する meta_query の例
$args = [   'post_type'      => 'product',   'posts_per_page' => 10,   'meta_query'     => [      [         'key'     => 'price',         'value'   => 1000,         'compare' => '>=',         'type'    => 'NUMERIC',      ],   ],]; $products = new WP_Query( $args );

このコードのポイントは、compareだけでなくtypeも指定している点です。>=を書いていても、比較対象の扱いが合っていなければ期待した結果になりません。数値比較ではNUMERIC、日付比較では保存形式に合う型を明示して結果を比べます。

日付の場合は、保存形式がとても重要です。公式リファレンスでも、DATE 型と BETWEEN の組み合わせは、日付が YYYY-MM-DD 形式で保存され、その形式で比較される場合に使う説明になっています。ACFなどのフィールドを使っている場合は、表示形式ではなく保存形式を先に確認します。

6. 複数条件は relation を最後に確認する

meta_query に複数の条件を書く場合、relation で条件同士の関係を指定します。AND はすべての条件を満たす投稿、OR はどれか1つでも満たす投稿です。指定しない場合は、基本的に AND と考えて確認すると分かりやすいです。

ただし、relation は複数条件の話です。1条件だけの meta_queryrelation を疑っても、原因にはなりにくいです。まず1条件で期待どおり取れることを確認してから、2条件目を追加します。

クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。

PHPrelation-meta-query.php価格条件と在庫条件を AND で組み合わせる例
$args = [   'post_type'      => 'product',   'posts_per_page' => 10,   'meta_query'     => [      'relation' => 'AND',      [         'key'     => 'price',         'value'   => 1000,         'compare' => '>=',         'type'    => 'NUMERIC',      ],      [         'key'     => 'stock_status',         'value'   => 'in_stock',         'compare' => '=',      ],   ],]; $products = new WP_Query( $args );

このコードのポイントは、価格条件と在庫条件の両方を満たす投稿だけが対象になる点です。「価格条件または在庫条件のどちらかを満たせばよい」なら、relationORに変えます。結果が少なすぎるときはANDが厳しすぎないか、結果が多すぎるときはORが広すぎないかを確認します。

7. meta_query 以外の条件で除外されていないか確認する

meta_query が正しくても、別の WP_Query 引数で投稿が除外されることがあります。たとえば post_type が違う、post_status が公開済みに合っていない、tax_query と組み合わせた結果として対象がなくなる、といったケースです。

トラブル時は、条件を一度に全部見るのではなく、外側から削っていきます。post_type だけ、次に meta_query 1条件、次に tax_query、最後に並び順やページネーションという順に戻していくと、どこで崩れるかが見えます。

確認する場所見落としやすい点切り分け方
post_type投稿タイプ名が違うpost_type だけで1件取れるか確認する
post_status下書きや非公開を期待している公開済みだけを対象にしていないか確認する
tax_query分類条件で対象が消えている一度 tax_query を外す
posts_per_page / pagedページによって見えていないposts_per_page を小さくして1ページ目で確認する
orderby並び順だけの問題を絞り込み問題と誤解しているまず取得できるかを確認し、その後で並び順を見る

条件を減らして「どこまでは動くか」を確認し、0件になった条件を特定します。

最後はチェックリストで原因をつぶす

保存値、比較方法、型、複数条件を別々に確認します。1件返る最小例へ戻し、条件を1つずつ足せば、結果を変えた指定を特定できます。

公式リンク

公式ドキュメント

meta_queryの最終判断

  • 0件になる境界の条件を1つに特定した
  • 未保存・空値・同じキーの複数値を区別した
  • 保存値の実物とkey・value・compare・typeの組み合わせが一致している
  • relationを変えた時のpost_countと投稿IDを比較した
  • 最終的なquery_varsと対象投稿が意図どおりになっている
WP Query BuilderBuilderで条件を組み直す条件を選び、WP_Queryのコードを画面で作れます。Builderでクエリを作る

この記事を書いた人

Huddly

Web制作 / フロントエンドエンジニア

WordPressとフロントエンド実装で迷いやすい点を、公式情報と検証結果を分けながら、初学者にも追いやすい順序で整理しています。

この記事の検証情報

検証環境

WordPress
7.1
PHP
8.3.33
テーマ
wpq-media + DDEV
対象
カスタム投稿 / taxonomy / meta_query

更新履歴

  • 2026年9月1日 初回公開

この記事を活用する

あとで見返す・共有する

お気に入りに保存できます。役に立ったポイントは、いいねや共有で教えてください。

任意のご支援 役に立ったときだけ、活動を応援できます OFUSEはサイト・記事制作に使います。支援の有無で、読める内容や使える機能は変わりません。