web-dev-qa-db-ja.com

WP_Queryを使用してカスタムフィールドに格納されている配列を検索する方法を教えてください。

"daysonair"というカスタムフィールドを含む "on-air"というカスタム投稿タイプがあります。このフォームには、曜日ごとにチェックボックスがあります。

投稿を追加または更新すると、チェックされたアイテムはカスタムフィールドに配列として格納されます。

WP_Query()検索にそのカスタムフィールドを追加する方法がわかりません。

array( 'key' => 'daysonair',
       'value' => 'Thursday',
       'compare' => 'IN' )

私は運なしで何種類もの比較を試みました。

データベース内のデータは次のとおりです。

a:5:{s:6:"Monday";s:6:"Monday";s:7:"Tuesday";s:7:"Tuesday";s:9:"Wednesday";s:9:"Wednesday";s:8:"Thursday";s:8:"Thursday";s:6:"Friday";s:6:"Friday";}

平日がすべてチェックされたところ。私は木曜日が配列に入っているかどうかだけを見ています。

2
Dave Navarro

直列化された配列内を検索するのは困難で非効率的です。スロー。次の純粋なSQLがそれを行います。

SELECT *
FROM `wp_postmeta`
WHERE `meta_key` LIKE 'daysonair'
AND `meta_value` LIKE '%thursday%'
LIMIT 0 , 100

このようなものはWP_Queryに似たようなことをさせるでしょう:

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
    array(
      'key' => 'daysonair',
      'value' => 'thursday',
      'compare' => 'LIKE',
    )
  )
);
$q = new WP_Query($args);
var_dump($q);

しかし、ワイルドカード(%)を含むLIKEクエリは非常に遅くなります。クエリは、テーブル内のすべての行で一致を確認する必要があります。

また、「木曜日」の任意の出現箇所が一致するため、エラーが発生しやすくなります。たとえば、添付ファイルのaltテキストの内容と一致します。

問題は、シリアライズ文字列がPHP構文であることです。 MySQLは、他の文字列と同じように扱うこと以外に何をすべきかわかりません。

唯一の本当に良い解決策、そしてあなたの場合それが可能であるかどうか私は知らない、データがデータベースに格納される方法を変えることです。データを検索する必要がある場合は、シリアル化された文字列として格納しないでください。各データは、独立したキーと値のペアとして格納する必要があります。

5
s_ha_dum

カスタムのLIKEクエリはのようなになりますが、私は個人的には(s_ha_dumがコメントで述べたように)最も単純な実装以外にはそれを信頼しません。

より良い解決策は カスタムの分類法を作成すること "曜日"を指定すること - そして 税金クエリを実行すること それに基づいて行うことです。これは、分類システムが設計されているものとまったく同じ種類のものです。

$args = array(
    'tax_query' => array(
        array(
            'taxonomy' => 'days_of_week',
            'field' => 'slug',
            'terms' => 'wednesday'
        )
    )
);
$query = new WP_Query( $args );
1
MathSmath