シリアライズ化されたカスタムフィールドからどのようにmeta_queryを指定するか思案

作成日:

まず、解決策ではないです。こんな感じでいけるかな、というアイディアレベルです。

WordPressでは基本的な仕様に沿えば、カスタムフィールドはwp_postmetaテーブルにmeta_idpost_idと共にカスタムフィールドの名前であるmeta_keyとその値であるmeta_valueが文字列として保存されます。

しかし、カスタムフィールドを管理するプラグインでは、1つのmeta_valueの中に複数の値を格納した配列をシリアライズ化して保存するようになっています。

配列を保存することで、

  • チェックボックスなどの複数の値をまとめて保存出来る
  • wp_postmetaが増え続けるのを防ぐ
  • ACFのリピーターフィールドのように、同じ入力項目を複数個保存出来る

などの利点があり、カスタムフィールドを非常に効果的に利用することが可能になります。

一方、これらのカスタムフィールドの値で表示する投稿を絞り込もうとすると、通常のmeta_queryが使用出来なくなります。

query_posts(WP_Queryクラス)でカスタムフィールドを使う https://elearn.jp/wpman/column/c20110915_01.html

カスタムフィールドに関連する条件を配列で指定。

通常、meta_queryは

PHP
array( 'relation' => 'AND',
	array(
		'key' => (検索条件とするカスタムフィールドの名前),
		'value' => (検索条件とするカスタムフィールドの値),
		'compare' => '=',
		'type' => 'CHAR'
	),
)

と記述しますが、このままだと、シリアライズ化されたmeta_valueからうまく値を検索することが出来ません。

単純な「キーワード一致」であれば、compareをLIKEにしてやれば取り敢えずは検索してくれますが、数値の検証や比較などは難しいでしょう。

シリアライズ化配列のmeta_query取得は前から課題にはなっていたので、そろそろ良い解決策が出てきているかな、と思いながら検索してみたのですが決定的なものを見つけることは出来ませんでした。

そこで打開策としては、

  1. post_typeやtax_queryのクエリパラメータを指定する
  2. さらにmeta_valueを指定せず、meta_keyだけを指定する
  3. 1, 2でquery_postsやget_postsで条件にマッチするクエリを取得する
  4. 3のクエリをforeachで回して、各投稿のカスタムフィールドを配列として受け取り、検索条件を当てはめて投稿のフィルタリングを行う

としてみました。

余り複雑な検索は出来ないけど、基本的には

  • 文字列の一致
  • 配列の合致
  • 数値(または日付)の範囲

が出来れば大体の検索は可能だと思うのでシンプルに設計出来るのではなかろうかと。
ただ、最終的なクエリを取得するまでに1回余分にforeachを回さないと行けない分、処理がもたつくかもしれないなーと。

もし元々の検索対象数が100件以下なら、予めキャッシュでテーブル表を作っておいて、DataTablesなどのフィルタリングjQueryプラグインを利用するのも簡単で良いかもしれません。

取り敢えず書けたら実装してみよう。

物草 灸太郎

WordPressでホームページを制作しつつ、休日は畑を耕したりDIYを楽しんでいます。

コメントをどうぞ

  • メールアドレスが公開されることはありません。
  • コメント欄にURLは入力できません。
  • このサイトはreCAPTCHAによって保護されており、Googleのプライバシーポリシー利用規約が適用されます。