【入門編】初心者向け:WP_Queryの「fields => ‘ids’」を活用したクエリ軽量化の基本 – WordPress 内部コア・データベース構造とパフォーマンス最適化解析バイブル

WordPress の世界へようこそ! 🚀

「WordPress 内部コア・データベース構造とパフォーマンス最適化」という、ちょっと耳慣れないかもしれませんが、実は WordPress を深く理解し、よりパワフルに使いこなすための超重要テーマに、今日は一緒に飛び込んでみましょう!

特に今回は、プログラミング初学者の方や、他の言語から WordPress 開発に挑戦されている皆さんにとって、まさに「目から鱗」が落ちるような、しかし非常にシンプルで強力なテクニックをご紹介します。それは `WP_Query` の `fields => ‘ids’` を活用したクエリ軽量化の基本 です。

「`WP_Query`? `fields`? ID だけ?」って思われたかもしれませんね。大丈夫です! 全てを丁寧に、まるで隣で一緒にコードを書いているかのように、分かりやすく解説していきますよ。ここをクリアすれば、WordPress のデータベース操作の基本がバッチリマスターできますから、安心してくださいね。

—

データベースとの対話、`WP_Query` の「お財布事情」を考えよう 💰

WordPress は、私たちが投稿を書いたり、ページを作成したり、プラグインやテーマを設定したりするたびに、その情報をデータベースに保存しています。そして、ウェブサイトにアクセスがあったとき、WordPress はデータベースに「こういう情報が欲しいんだけど、出してくれない?」とお願いするんです。この「お願い」のやり取りを司っているのが、今回主役の `WP_Query` という仕組みなんです。

例えるなら、`WP_Query` はデータベースという図書館の司書さん。私たちが「〇〇というタイトルの本を探しています」と伝えると、司書さんは書棚からその本を探し出してきてくれます。

取得する情報の「量」で差が出る!

ここで、ちょっと考えてみてほしいんです。図書館で本を探すとき、

  • 本のタイトルと著者名だけ知りたい
  • 本の目次まで全部読みたい
  • 本の内容を丸ごと一字一句コピーしたい

この3つでは、司書さんが棚から本を持ってくるまでの手間や、私たちが本を受け取るときの「重さ」が全然違いますよね?

`WP_Query` も全く同じで、データベースにお願いする情報が多ければ多いほど、データベースは一生懸命働かなければなりません。これは、サーバーに余計な負荷をかけ、ウェブサイトの表示速度を遅くしてしまう原因にもなり得ます。

`WP_Query` の「お財布事情」を軽くする魔法:`fields => ‘ids’` ✨

そこで登場するのが、今回ご紹介する `fields => ‘ids’` という、まるで魔法のようなオプションなんです!

これは、`WP_Query` に「投稿のデータは全部いらないよ! 投稿の『ID』だけでいいから、それを全部リストアップしてちょうだい!」とお願いする強力な指示なんです。

ID だけを取得する、ということは、投稿のタイトル、本文、アイキャッチ画像、著者情報…といった、本来必要のない情報までまるっと取得しなくて良くなります。これは、データベースが「本の内容を丸ごとコピーする」のではなく、「本の背表紙に書いてあるタイトル(ID)をリストアップする」くらいの仕事量で済む、ということです。

その結果、データベースへの負荷は劇的に軽くなり、WordPress の処理速度が速くなる、というわけなんです。まさに、「必要最低限の情報だけをもらう」という、賢いデータベースとの付き合い方ですよね。

—

実際に `fields => ‘ids’` を使ってみよう! ✍️

では、具体的にコードで見ていきましょう。

基本的な `WP_Query` の使い方をおさらい

まずは、通常の `WP_Query` で「最新の5件の投稿のタイトルと本文」を取得する場合を考えてみましょう。

5, // 表示する投稿数を5件に指定
);

$latest_posts = new WP_Query( $args );

if ( $latest_posts->have_posts() ) :
while ( $latest_posts->have_posts() ) : $latest_posts->the_post();
?>

投稿が見つかりませんでした。

‘;
endif;
?>

このコードでは、`WP_Query` はデータベースから5件の投稿の「ID」だけでなく、「タイトル」「本文(抜粋)」「パーマリンク」といった、表示に必要な全ての情報を取得しています。

`fields => ‘ids’` を追加してみよう!

では、このコードに `fields => ‘ids’` を追加して、ID だけを取得するように変更してみましょう。

5, // 表示する投稿数を5件に指定
‘fields’ => ‘ids’, // ★ ここで「IDだけ」と指定!
);

$latest_post_ids = new WP_Query( $args );

// $latest_post_ids には、投稿オブジェクトの配列ではなく、
// 投稿IDの配列が格納されます。

if ( ! empty( $latest_post_ids->posts ) ) : // $latest_post_ids->posts が空でないかチェック
echo ‘

最新の投稿IDリスト:

‘;
echo ‘

    ‘;
    foreach ( $latest_post_ids->posts as $post_id ) {
    // $post_id は投稿のIDそのものです。
    echo ‘

  • ‘ . esc_html( $post_id ) . ‘
  • ‘; // IDをリスト表示
    }
    echo ‘

‘;

// もし、取得したIDを使って後で投稿オブジェクトが必要になった場合…
// 例: $single_post_object = get_post( $post_id );
// echo ‘

ID: ‘ . $post_id . ‘ のタイトル: ‘ . get_the_title( $post_id ) . ‘

‘;

else :
echo ‘

投稿が見つかりませんでした。

‘;
endif;

// $latest_post_ids->have_posts() や $latest_post_ids->the_post() は、
// ‘fields’ => ‘ids’ を指定した場合は使えません。
// なぜなら、取得しているのは投稿オブジェクトではなくIDの配列だからです。
?>

コードのポイント解説:

  • `’fields’ => ‘ids’`: これが今回の主役! これを指定することで、`WP_Query` はデータベースから投稿のIDの配列だけを取得します。
  • `$latest_post_ids->posts`: `fields => ‘ids’` を指定した場合、取得したIDの配列は `$query->posts` プロパティに格納されます。
  • `! empty( $latest_post_ids->posts )`: IDが取得できたかどうかを確認しています。`$latest_post_ids->posts` は配列なので、`empty()` でチェックするのが適切です。
  • `foreach ( $latest_post_ids->posts as $post_id )`: 取得したIDの配列をループ処理して、一つずつIDを取り出しています。`$post_id` には、投稿のID(数字)が格納されています。
  • `echo ‘
  • ‘ . esc_html( $post_id ) . ‘
  • ‘;`: 取得したIDをリスト形式で表示しています。`esc_html()` でセキュリティ対策も忘れずに!

  • `wp_reset_postdata()` は不要: `fields => ‘ids’` を指定した場合、投稿オブジェクト自体を操作するループ(`the_post()` など)を行わないため、`wp_reset_postdata()` は不要になります。

実行結果例

上記のコードを実行すると、以下のような結果が表示されるはずです。(IDは実際の環境によって異なります)

最新の投稿IDリスト:

  • 123
  • 118
  • 115
  • 109
  • 105

このように、投稿のタイトルや本文などの情報は一切表示されず、純粋に投稿のIDだけがリストアップされます。

—

どんな時に `fields => ‘ids’` が役立つ? 🤔

「ID だけ取ってどうするの?」と思われるかもしれませんね。このテクニックが真価を発揮するのは、以下のような場面です。

1. ID を使って別の処理を行いたい場合

例えば、取得したIDのリストを元に、別の条件で投稿を取得し直したり、特定の投稿だけを個別に取り出して詳細を表示したい場合などです。

5,
‘fields’ => ‘ids’,
‘post_status’ => ‘publish’, // 公開済みの投稿のみ
);
$latest_post_ids_query = new WP_Query( $args_ids );
$latest_post_ids = $latest_post_ids_query->posts; // IDの配列を取得

if ( ! empty( $latest_post_ids ) ) {
echo ‘

取得したIDリスト: ‘ . implode(‘, ‘, $latest_post_ids) . ‘

‘;

// 次に、これらのIDの中から「特定のカテゴリに属する投稿」だけを抽出したい場合
$args_specific = array(
‘post__in’ => $latest_post_ids, // ここで取得したIDリストを指定!
‘posts_per_page’ => 3, // その中からさらに3件だけ表示
‘category_name’ => ‘featured’, // 例: ‘featured’ カテゴリ
‘fields’ => ‘ids’, // ここでもIDだけ取得(もし必要なら)
);
$featured_post_ids_query = new WP_Query( $args_specific );
$featured_post_ids = $featured_post_ids_query->posts;

if ( ! empty( $featured_post_ids ) ) {
echo ‘

Featured カテゴリの投稿ID: ‘ . implode(‘, ‘, $featured_post_ids) . ‘

‘;

// さらに、これらのIDを使って投稿オブジェクトを取得し、タイトルを表示
$args_titles = array(
‘post__in’ => $featured_post_ids,
‘posts_per_page’ => -1, // 全て表示
‘fields’ => ‘id=>title’, // IDとタイトルをペアで取得する高度な指定!
);
$post_titles_query = new WP_Query( $args_titles );
$post_titles = $post_titles_query->get_posts(); // get_posts() は配列を返します

echo ‘

Featured カテゴリの投稿タイトル:

‘;
echo ‘

    ‘;
    foreach ( $post_titles as $id => $title ) {
    echo ‘

  • ‘ . esc_html( $title ) . ‘ (ID: ‘ . esc_html( $id ) . ‘)
  • ‘;
    }
    echo ‘

‘;

} else {
echo ‘

Featured カテゴリに該当する投稿は見つかりませんでした。

‘;
}
} else {
echo ‘

投稿が見つかりませんでした。

‘;
}
?>

このように、一度 ID を取得しておくと、その ID を使ってさらに絞り込みをかけたり、別のクエリに渡したりといった、柔軟なデータ操作が可能になります。

2. 投稿一覧の「数」だけが必要な場合

例えば、「公開されている投稿の総数を取得したい」といった場合、全投稿のデータを取得する必要はありません。`fields => ‘ids’` を使って ID の数を数えるだけで、非常に軽量に処理できます。

-1, // 全ての投稿を取得
‘fields’ => ‘ids’, // IDだけ取得
‘post_status’ => ‘publish’, // 公開済みの投稿のみ
);

$all_posts_query = new WP_Query( $args );
$total_posts = count( $all_posts_query->posts ); // IDの数を数える

echo ‘

現在、公開されている投稿の総数: ‘ . esc_html( $total_posts ) . ‘ 件

‘;
?>

注意点: `posts_per_page` に `-1` を指定して全ての投稿の ID を取得する際は、投稿数が非常に多いサイトではメモリを大量に消費する可能性があるので注意が必要です。そのような場合は、`’fields’ => ‘ids’` を使わず、`$wpdb->get_var(“SELECT COUNT()…”)` のような直接 SQL を実行する方が効率的かもしれません。これは少し高度な話になりますが、覚えておくと役立ちます。

3. データベース負荷を極限まで減らしたい場合

パフォーマンスが最優先される場面では、`fields => ‘ids’` は非常に有効な手段です。特に、テーマファイルやプラグインの初期化処理など、サイトの表示に直接関わる部分で、必要のないデータ取得を避けることで、体感速度を向上させることができます。

—

陥りやすい文法エラーとその回避策 ⚠️

`fields => ‘ids’` を使う上で、初心者がつまずきやすいポイントがいくつかあります。

エラー1: `fields => ‘ids’` を指定したのに、ループ処理 (`the_post()`) が動くと思ってしまう

原因: `fields => ‘ids’` を指定すると、`WP_Query` は投稿オブジェクトではなく、ID の配列を返します。そのため、`the_post()` のような、投稿オブジェクトをグローバル変数 `$post` にセットする関数は正しく動作しません。

解決策: `fields => ‘ids’` を指定した場合は、`$query->posts` から ID の配列を取得し、`foreach` ループで処理するようにしましょう。`the_post()` や `the_title()` は使えません。

// NG: ‘fields’ => ‘ids’ を指定したのに、the_post() を使おうとする
$args = array(
‘posts_per_page’ => 5,
‘fields’ => ‘ids’,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) { // this will be false or behave unexpectedly
while ( $query->have_posts() ) {
$query->the_post(); // ★ ここでエラー! $post がセットされない
// the_title(); // これも使えません
}
}

// OK: IDの配列を直接ループする
$args = array(
‘posts_per_page’ => 5,
‘fields’ => ‘ids’,
);
$query = new WP_Query( $args );
if ( ! empty( $query->posts ) ) {
foreach ( $query->posts as $post_id ) {
echo ‘ID: ‘ . esc_html( $post_id ) . ‘
‘;
// $post_id を使って get_the_title( $post_id ) などで情報を取得
echo ‘タイトル: ‘ . esc_html( get_the_title( $post_id ) ) . ‘
‘;
}
}

エラー2: `$query->have_posts()` や `$query->the_post()` を使おうとする

原因: 上記のエラー1と関連しますが、`fields => ‘ids’` を指定した場合、`WP_Query` オブジェクトは投稿オブジェクトのリストではなく、ID の配列を保持しています。`have_posts()` は内部で `$this->posts` を参照しますが、その中身が期待する投稿オブジェクトの配列ではないため、正しく動作しません。

解決策: ID の配列が格納されている `$query->posts` が空でないか (`! empty()`) で判断し、`foreach` でループ処理を行います。

エラー3: 取得した ID を直接使おうとして、投稿オブジェクトが必要だと勘違いする

原因: `fields => ‘ids’` で取得できるのは、あくまで投稿の ID(数字)だけです。投稿のタイトルや本文などの情報が必要な場合は、別途 `get_post()` や `get_the_title()` などの関数を使って、その ID から情報を取得する必要があります。

解決策: 取得した `$post_id` を引数として、`get_post( $post_id )` や `get_the_title( $post_id )` などを呼び出しましょう。

2,
‘fields’ => ‘ids’,
);
$query = new WP_Query( $args );

if ( ! empty( $query->posts ) ) {
foreach ( $query->posts as $post_id ) {
// ★ $post_id は単なる数字です。
echo ‘投稿ID: ‘ . esc_html( $post_id ) . ‘
‘;

// ★ タイトルが必要なら get_the_title() を使う
$post_title = get_the_title( $post_id );
echo ‘タイトル: ‘ . esc_html( $post_title ) . ‘
‘;

// ★ 投稿オブジェクト全体が必要なら get_post() を使う
$post_object = get_post( $post_id );
if ($post_object) {
// $post_object->post_content などで本文にアクセス可能
// echo ‘本文抜粋: ‘ . wp_trim_words( $post_object->post_content, 30 ) . ‘
‘;
}
}
}
?>

—

まとめ:`fields => ‘ids’` は WordPress パフォーマンスの秘密兵器! 🚀

いかがでしたでしょうか? `WP_Query` の `fields => ‘ids’` という、一見地味ながらも非常に強力なテクニックについて解説しました。

  • `fields => ‘ids’`: 投稿の ID の配列だけを取得し、データベース負荷を劇的に減らします。
  • 適した場面: ID を元に別の処理を行いたい場合、単に件数だけを知りたい場合、パフォーマンスを最優先したい場合など。
  • 注意点: `the_post()` などのループ関数は使えず、ID の配列 (`$query->posts`) を `foreach` で処理する必要があります。

この `fields => ‘ids’` をマスターすれば、あなたの WordPress 開発は一段と効率的になり、より高速で快適なウェブサイト構築への道が開けます。

WordPress の内部構造は、知れば知るほど奥深く、そして面白いものです。今回学んだ `fields => ‘ids’` を皮切りに、これからも色々な「WordPress の極限の知見」を探求していきましょう!

もし分からないことがあれば、いつでも聞いてくださいね。応援しています! 💪

タイトルとURLをコピーしました