web-dev-qa-db-ja.com

Meta_fieldとして配列を持つmeta_queryを作成するにはどうすればよいですか?

これが私のクエリの引数です。

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
        )
    )
);

これはtopicsが文字列のときに動作しますが、それが配列のときはnotです。 topicsが例えばarray( 'sports', 'nonprofit', etc. )の場合にこのクエリが機能するようにします。

Meta_keyとして配列を使ってメタクエリを構築する方法はありますか?

13
mike23

可能な値の配列をクエリに送る

データベース内の値が文字列で、クエリにいくつかの値を渡したい場合

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => array ( 'sports', 'nonprofit', 'community' ),
            'compare' => 'IN'
        )
    )
);

直列化されたデータ配列で特定の値を検索する

データベース内の値が複数のトピックの配列であり、その配列内の単一のトピックを検索する場合(データベース内の配列はそのまま検索できますが、直列化された形式でデータベースに存在します。文字列も):

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
            'compare' => 'LIKE'
        )
    )
);

比較値として 'LIKE'を使用することは、あなたが望んでいたかもしれないほど明確な命令ではありませんが、それを使うのが最良の選択です。

それ以外に、 meta_key "topics"が設定されているすべての投稿を手動で検索するか、ループ内の値を確認してその条件で投稿を表示するしかありません。 。

27
Johannes Pille

Johannesの応答から外れるために、それは直列化された配列なので、もしあなたがユーザーIDのようなものを格納しているのなら(これは私の場合でした)、あなたはそれを少し別様に扱う必要があるかもしれません。

ポストメタは次のように保存されていました:

array( "1", "23", "99");

そうです、それらは整数ですが、update_post_metaを通して文字列として保存されていました。

'meta_query' => array(
            array(
                    'key'     => 'my_meta_key',
                    'value'   => serialize( strval( 1 ) ),
                    'compare' => 'LIKE'
                )
            )

だからあなたは実際にあなたが探しているもののシリアル化された文字列バージョンとLIKE比較をしています。私はこのようなものを機能させるためにかなりの時間を費やしました、そしてこれまでのところこれは私が思い付くことができる最高でした。

12
sMyles

@sMylesの回答からのもう1つのわずかな改善。

IDが文字列(フォーム入力から取得された場合など)と整数(例:update_post_meta($post_id, authorized_users', array(get_current_user_id()));)の両方として格納されている場合があります。これはwp_set_object_terms()のよく知られた問題のようなもので、ここで用語IDを使って用語を設定することができますが、最初にそれらを整数としてキャストしないと、50%の確率でそれらの番号を新しい用語として作成できます。代わりに名前。

私のテストサイトのデータベースからのそのようなケースの抜粋からわかるように、これはそれらが直列化された配列に全く異なって格納されることになるかもしれません:

a:1:{i:0;s:1:"1";} // 's' for 'string', also note the double quotes
a:1:{i:0;i:1;} // 'i' for 'integer', no quotes

上記の両方が、print_r()を介してフィードされると、

Array
(
    [0] => 1
)

これを修正するために、relationと、文字列ではなく整数として値をキャストする別のバージョンのクエリを追加して、meta_queryを少し微調整しました。

これが最終結果です。

        'meta_query' => array(
            'relation' => 'OR', // Lets it know that either of the following is acceptable
            array(
                'key' => 'bcm_enm_authorized_users',
                'value'   => serialize(strval(get_current_user_id())), // Saved as string
                'compare' => 'LIKE'
            ),
            array(
                'key' => 'bcm_enm_authorized_users',
                'value'   => serialize(intval(get_current_user_id())), // Saved as integer
                'compare' => 'LIKE'
            ),
        ),

編集: /この方法は配列のインデックスと衝突する危険性があることに気づきました。配列にない場合、誰かが不正にマテリアルにアクセスする可能性がありますが、ユーザーIDはインデックスとして表示されます。そのため、この works について議論した場合は、代わりに@sMylesメソッドを使用できるように、検索する値を保存する前に必ず文字列としてキャストするようにしてください。 。

3
Kaji

ヨハネスの答えに行きます。しかし、私はそれを改善したいのです。そのmeta_queryを使うと、あなたはこのようなケースを満たすでしょう

あなたの価値は

array('sports','movies', 'sports2');

検索時

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
            'compare' => 'LIKE'
        )
    )
);

結果は「sport」と「sport2」の両方を返します。

これを修正するには、meta_query引数を次のように変更します。

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports";',
            'compare' => 'LIKE'
        )
    )
);

これは、値がデータベース内でシリアル化され、各項目がセミコロンで区切られるためです。したがって、上記の引数は機能します。

値の中の項目が数値の場合は、二重引用符を削除するだけです。 "

$args = array(
        'post_type' => 'news',
        'meta_query' => array(
            array(
                'key' => 'topics',
                'value' => '1;',
                'compare' => 'LIKE'
            )
        )
    );
2
Ha Doan Ngoc

私は今日似たようなもので立ち往生しました。複数の関連ユーザー(配列)を持つACF(Advanced Custom Fields)関係フィールドを照会する必要があります。

Phpでフィールドを更新した後、クエリが機能しませんでした。 ACF UIを介してそれを更新した後、クエリは機能しました。

問題は、私のphpコードが関係値をint-valuesに設定し、UIがそれをstring-valuesに設定することでした。両方の作業を確実にするために、ここでこのクエリを使用します(ここの例に合わせて)。

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'topics',
            'value' => '1;',  // works for int-array
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'topics',
            'value' => '"1"',  // works for string-array
            'compare' => 'LIKE'
        ),
    )
);
1
Julian Stark