未分類

WP「meta_query」で「OR」を使うと危険です

  • このエントリーをはてなブックマークに追加

前提:すでに運用されているデータに、チェックボックス「add_flag」を追加して、チェックされているときは一覧から除外したい

WordPressで絞り込みに必要なカスタムフィールドを追加した際に
既存のデータには、項目が反映されていないので
データ上は「NOT EXISTS」状態になっています。
このままmeta_queryを構成しようとすると

$meta_query[] = array(
‘relation’ => ‘OR’,
array(
‘key’ => ‘add_flag’,
‘value’ => true,
‘compare’ => ‘!=’
),
array(
‘key’ => ‘add_flag’,
‘compare’ => ‘NOT EXISTS’,
)
);

こんな書き方になると思います。
文法上は、決して間違ってはいないです

が・・・・・

meta_queryで「relation」に「OR」を使っていると、とんでもなく処理に時間がかかってしまいます。
取得するデータが多くなるほどに、処理時間っがとんでもなく延びていきます。

だったらどうすれば良いのか
A.カスタムフィールドではなく、タクソノミで項目を作って処理する。
B.除外するデータのIDを取得して「post__not_in」で除外する。
の2通りの対処方法が考えられます。

今回すでに、カスタムフィールド追加してしまってたので
「B」の方法で対応してみました。

1.query発行前に、除外データのIDを取得して
$not_in = array();
$args = array(
‘post_type’ => ‘gallery’,
‘posts_per_page’ => -1,
‘meta_query’ => array(
array(
‘key’ => ‘add_flag’,
‘compare’ => ‘==’,
‘value’ => true
)
),
);
$notin_query = new WP_Query( $args );
if ( $notin_query->have_posts() ) :
while ( $notin_query->have_posts() ) : $notin_query->the_post();
$not_in[] = get_the_id();
endwhile;
endif;

2.「post__not_in」を使ってqueryを発行する。

これで、各段に処理速度が上がります。

一見余計なqueryを発行しているので、余計に時間がかかりそうですが
それほどまでに、meta_queryでの「OR」の使用はリスクが大きいのでご注意ください。

  • このエントリーをはてなブックマークに追加