0件ならkeyとvalueを先に確認する
対象投稿を1件決め、管理画面またはget_post_meta()で、meta_queryのkeyとvalueが実際に保存されているか確認します。未保存と空文字はmetadata_exists()で切り分けます。保存された値が合っていれば条件を1つに減らし、compare、type、valueの形、relationを順に戻します。
画面の表示名ではなく、保存されているキーと値を確認してください。
0件・出すぎる・数値や日付が合わない症状を分ける
エラーが出なくても、投稿が0件になる、対象外まで出る、数値や日付だけ合わない、という形で問題が現れます。症状を次の表へ当てはめてください。
| 症状 | 最初に疑う場所 | よくある原因 |
|---|---|---|
| 投稿が1件も出ない | key / value / post_type | 保存されているメタキー名や値が想定と違う |
| 出るはずの投稿だけ漏れる | compare / type | 数値や日付を文字列として比較している |
| 出てほしくない投稿まで出る | relation / compare | AND と OR、IN と LIKE の使い分けが違う |
| BETWEEN が効かない | value の形 / type | 配列ではない、または保存形式と比較形式が違う |
| ACFの値で絞れない | 保存されている値 | 画面上の表示形式と実際に保存されている値が違う |
meta_queryの配列の形そのものが分からない場合はmeta_queryの基本構造へ戻ります。ACF固有の値が関係する時は、ACFの値が検索できない時の確認ポイントも、実際に保存されている値を見ながら確認してください。
まず疑う順番
- 1対象投稿にメタキーと値が本当に保存されているか確認する
- 2post_type と posts_per_page だけの最小クエリで投稿が出るか確認する
- 3meta_query を1条件だけに減らす
- 4compare と value の形が合っているか確認する
- 5数値や日付なら type を確認する
- 6複数条件なら relation を最後に確認する
meta_queryの条件を1つずつ確認する
原因候補を整理したら、実際に保存されている値、最小クエリ、比較方法、型、複数条件、ほかの引数の順に確認します。
1. 保存されている key と value を確認する
meta_query では、管理画面に表示されている項目名ではなく、保存されているメタキー名を指定します。たとえば画面上では「価格」と表示されていても、実際のキーが price、product_price、_price のどれなのかは別問題です。
また、保存されている値は、画面の見た目と一致するとは限りません。チェックボックス、セレクト、日付フィールド、プラグインが作るフィールドでは、表示上の文字と保存される値が違うことがあります。まず対象投稿1件で、保存されている key と value を確認します。

meta_queryのkeyにprice、valueに実際に保存されている値を指定できるか確認します。
コードで確認する場合は、まず対象投稿のIDを1つ決めて、その投稿に保存されている値を見ます。これは原因切り分け用なので、公開画面にそのまま出す前提ではなく、検証環境で一時的に使う確認コードとして扱います。
原因を切り分けるための一時的な確認コードです。ローカルなどの検証環境だけで使い、確認後は削除してください。
$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 ではなく、投稿タイプや投稿ステータスなど別の条件にあります。
原因を切り分けるための一時的な確認コードです。ローカルなどの検証環境だけで使い、確認後は削除してください。
$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件以上ある」と分かっているキーと値で試します。存在が確認できているデータを使うことで、構文の問題なのか、値の問題なのかを分けやすくなります。
原因を切り分けるための一時的な確認コードです。ローカルなどの検証環境だけで使い、確認後は削除してください。
$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は入れ子の配列として書きます。ここを崩すと、意図した条件として解釈されません。
LIKE、IN、BETWEENへ進む前に、まず=で保存値と完全一致するかを確認します。
4. compare と value の形が合っているか確認する
compare は、value をどう比較するかを指定します。= なら単一の値との一致、IN なら複数候補のいずれか、BETWEEN なら範囲指定、EXISTS ならキーの存在確認というように、比較の意味が変わります。
ここでよくあるのは、IN や BETWEEN を使っているのに value が配列になっていないパターンです。逆に、完全一致でよいのに LIKE を使ってしまい、想定より広くヒットすることもあります。
| 使いたい条件 | compare | value の形 |
|---|---|---|
| 値が完全一致する投稿だけ出したい | = | 'blue' のような単一値 |
| 複数候補のどれかに一致させたい | IN | array( 'blue', 'red' ) のような配列 |
| 範囲内の値に絞りたい | BETWEEN | array( 1000, 3000 ) のような2要素の配列 |
| 指定キーが存在する投稿を出したい | EXISTS | 通常は value を指定しない |
| 指定キーが存在しない投稿を出したい | NOT EXISTS | 通常は value を指定しない |
value の形が合っていないと、コードの見た目は近くても結果が変わります。とくに BETWEEN は、下限と上限を配列で渡す必要があるため、単一値を入れていないか確認してください。
5. 数値や日付は type を確認する
カスタムフィールドの値は、基本的に文字列として保存され、meta_queryのtypeを省略した比較型もCHARです。そのため、価格、点数、在庫数のような数値を文字列のまま比較すると、期待と違う結果になることがあります。
たとえば数値として 100 より大きいものを取りたい場合、type を指定しないままだと、意図した数値比較にならないことがあります。数値なら NUMERIC、日付なら保存形式に合った DATE や、日付文字列として比較できる形式を検討します。
クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。
$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_query で relation を疑っても、原因にはなりにくいです。まず1条件で期待どおり取れることを確認してから、2条件目を追加します。
クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。
$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 );このコードのポイントは、価格条件と在庫条件の両方を満たす投稿だけが対象になる点です。「価格条件または在庫条件のどちらかを満たせばよい」なら、relationはORに変えます。結果が少なすぎるときは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と対象投稿が意図どおりになっている
この記事の検証情報
検証環境
- WordPress
- 7.1
- PHP
- 8.3.33
- テーマ
- wpq-media + DDEV
- 対象
- カスタム投稿 / taxonomy / meta_query
更新履歴
- 2026年9月1日 初回公開
この記事を活用する
あとで見返す・共有する
お気に入りに保存できます。役に立ったポイントは、いいねや共有で教えてください。


