2

値の配列を使用して meta_query を実行し、シリアル化された配列に格納されているメタ値にすべてが存在するかどうかを検索しようとしています。これは可能ですか?

クエリの引数は次のとおりです (これはクラスにネストされていることに注意してください)。

$args = array(
    'post_type' => $this->posttype,
    'posts_per_page' => '9',
    'paged' => $paged,
    'orderby' => 'meta_value_num',
    'order' => 'DESC',
    'meta_key' => 'lumens',
    'meta_query' => array(
        array(
            'key' => 'mount',
            'value' => array('pendant' , 'wall'),
            'compare' => 'IN'
        )

    )
);

格納されたメタ データの例は、以下のようなシリアル化された配列にあります。

a:4:{i:0;s:7:"pendant";i:1;s:15:"surface-ceiling";i:2;s:4:"wall";i:3;s:14:"aircraft-cable";}

私のクエリは、何を試しても適切な結果を返しません。各値を配列ではなく別のメタキーに格納する必要があったことに気付きましたが、メタデータを変更するエントリがすでに非常に多くなっています。

アップデート:

@Leander アプローチと同様に、これは私の回避策でした。データベースにすでに大量のエントリがあるため、シリアル化された入力を変更したくなかったのですが、1 つ忘れていたことがありました。チェックボックス フィールドをシリアル化されたデータとしてネイティブに格納するCMB2 Developer Toolkitを利用していたことです。

// This is pulled from a user input
$meta_queries = array('pendent' , 'wall');

// Metaqueries are passed through loop to create single entries with the like comparison operator
foreach($meta_queries as $key => $value){

    $meta_query = array(
        'key' => '_tf_' . $key,

        // Serialize the comparison value to be more exact
        'value' => serialize(strval($value)),
        'compare' => 'LIKE',
    );

}

// Generate $args array
$args = array(

    'post_type' => $this->posttype,
    'posts_per_page' => '9',
    'paged' => $paged,
    'orderby' => 'meta_value_num',
    'order' => 'DESC',
    'meta_key' => 'lumens',
    'meta_query' => $meta_queries

);

データを入力している間、パフォーマンスの問題にあまり気づきませんでした。処理するデータが圧倒的に多い場合、このアプローチを作り直す必要があると思います。

4

3 に答える 3

7

同じ問題に遭遇しました...!

配列/カスタムフィールドにいくつかのタグを保存しており、検索フォームを使用して、ユーザーが複数のタグを検索できるようにする必要がある投稿をクエリしているため、基本的に配列を別の配列と比較する必要があります。

おそらく、各値を配列ではなく別のメタキーに格納する必要があったことに気づきましたが、メタデータを変更するエントリがすでに非常に多くあります。

それはかなりのオーバーヘッドを生み出すと思いますが、それはお勧めしません...

アプローチ/回避策

ユーザー入力を文字列として操作し、文字列から配列を作成してそのサイズを確認し、サイズに応じて、配列化されたデータでうまく機能する単一の LIKE 比較を作成しています。

$tags_string = get_query_var( 'p_tags' ); // form submitted data
$tags_array = explode( ',', $tags_string ); // create array

if ( count( $tags_array ) > 1 ) { // check if more then one tag
$meta_query['p_tags']['relation'] = 'AND';

foreach($tags_array as $tag) { // create a LIKE-comparison for every single tag
    $meta_query['p_tags'][] = array( 'key' => 'YOUR_KEY', 'value' => $tag, 'compare' => 'LIKE' );
}
} else { // if only one tag then proceed with simple query
    $meta_query['p_tags'] = array( 'key' => 'YOUR_KEY', 'value' => $tags_string, 'compare' => 'LIKE' );
}

Args 出力 (デモ)

[meta_query] => Array
        (
            [p_tags] => Array
                (
                    [relation] => AND
                    [0] => Array
                        (
                            [key] => basic_tags
                            [value] => adobe
                            [compare] => LIKE
                        )

                    [1] => Array
                        (
                            [key] => basic_tags
                            [value] => stone
                            [compare] => LIKE
                        )

                )

        )

注意:配列のサイズ、クエリする投稿の数などによっては、このソリューションが最もパフォーマンスが良いとは限らない場合があります。

別のアプローチは、WordPress クエリの FIND_IN_SET 拡張機能です。この gist を参照してください

パフォーマンスやコード品質の向上に関するご意見をお待ちしております。

于 2017-06-01T15:01:51.173 に答える