WordPressの深淵へようこそ。
多くの開発者は、`wp_posts`テーブルの`post_content`を直接叩いて検索クエリを投げ、データベースの悲鳴を聞くことになります。しかし、真のエンジニアは「検索」と「保存」を分離し、システム全体の負荷を最小化する術を知っています。
今日は、忘れ去られがちなカラム`post_content_filtered`を武器に、検索負荷を劇的に改善する戦略を伝授しましょう。
—
1. なぜ「post_content」だけでは足りないのか?
WordPressの`post_content`は、HTMLタグやショートコードが混在する「生のデータ」です。もしあなたが記事の本文から特定のキーワードを検索しようとすれば、MySQLは毎回この巨大な文字列をスキャンし、さらにHTMLタグを除去するような複雑な処理を強いられます。
これでは、記事数が増えるたびに検索速度は線形(あるいはそれ以上)に劣化します。
そこで登場するのが、`wp_posts`テーブルに眠る`post_content_filtered`です。本来は古いキャッシュ用に使われていたものですが、現代のWordPress開発では、ここを「検索用インデックスデータ」の格納場所として再定義します。
イメージ図:データの流れ
1. 保存時: `save_post`フックでコンテンツを整形・抽出
2. 格納: `post_content_filtered`に検索用テキスト(タグなし、整形済み)を保存
3. 検索: 全文検索エンジン(ElasticsearchやAlgolia)へこのカラムの値を同期
—
2. 賢い実装:save_postフックでデータを同期する
では、実際にコードを書いてみましょう。投稿が保存されるたびに、本文からHTMLタグを除去した純粋なテキストを`post_content_filtered`に格納するロジックです。
/
- 投稿保存時にコンテンツをフィルタリングして保存する
/
add_action(‘save_post’, ‘sync_filtered_content_for_search’, 10, 3);
function sync_filtered_content_for_search($post_id, $post, $update) {
// 自動保存やリビジョン、ゴミ箱への移動時は除外(無駄な書き込みを防ぐ鉄則です)
if (defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) return;
if ($post->post_type !== ‘post’) return;
// 1. 本文からHTMLタグを除去し、検索に適した状態にする
$clean_content = wp_strip_all_tags($post->post_content);
// 2. データベースの更新(再帰ループを避けるため wp_update_post ではなく直接SQLを叩くか、
// remove_action で一時的にフックを外すのがベストプラクティスです)
global $wpdb;
$wpdb->update(
$wpdb->posts,
[‘post_content_filtered’ => $clean_content],
[‘ID’ => $post_id],
[‘%s’],
[‘%d’]
);
}
このコードのポイント
- `wp_strip_all_tags`: 単なる`strip_tags`よりも強力で、WordPressの仕様に沿った安全なタグ除去を行います。
- 再帰防止: `wp_update_post`を使うと、再び`save_post`が発火して無限ループに陥ります。`$wpdb->update`で直接テーブルを叩くことで、コアの処理を汚さずに目的を達成できます。
—
3. 陥りやすい罠と解決策
初学者がこの実装でよくやるミスは、「タイミングの誤解」です。
- 罠1:`post_content_filtered`を直接編集フォームで使おうとする
- これは間違いです。このカラムはあくまで「検索用のキャッシュ」であり、管理画面の投稿エディタとは切り離して考えてください。
- 罠2:大量の投稿を一括更新する際の負荷
- `save_post`は1投稿ごとに発火します。もし既存の1万記事を移行するなら、`save_post`ではなく、WP-CLIを使ってスクリプトを実行してください。`wp db query`や独自のWP-CLIコマンドを組むのが、プロの選択肢です。
—
4. 次のステップ:全文検索エンジンとの連携
ここまでくれば、`post_content_filtered`には「いつでも検索可能なクリーンなデータ」が溜まっています。
あとは、このカラムをElasticsearchなどの全文検索エンジンに同期させるだけです。これにより、MySQLの`LIKE %keyword%`という、全データベースを停滞させる最悪のクエリから解放されます。
最後に
WordPressを「単なるブログツール」と捉えるか、「高度なデータ基盤」と捉えるか。その境界線は、こうした「データベースの物理構造をどう最適化するか」という視点にあります。
ここをマスターすれば、あなたはもう初学者ではありません。データの流れを支配し、パフォーマンスを自在に操るエンジニアへの第一歩を踏み出したのです。
質問があればいつでもどうぞ。WordPressの深淵は、まだまだ奥が深いですよ。