meta_fieldとして配列を使用してmeta_queryを作成するにはどうすればよいですか?


16

私のクエリの引数は次のとおりです。

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

これtopicsは文字列の場合は機能しますが、配列の場合は機能しませんtopicsたとえば、次の場合にこのクエリを機能させたいarray( 'sports', 'nonprofit', etc. )

meta_keyとして配列を使用してメタクエリを作成する方法はありますか?


明確にしてください- 「トピック」の保存値が配列であることを意味していますか?または、保存された値が文字列であり、配列内のクエリに複数の用語を渡したいですか?
MathSmath

@MathSmath、保存された値は配列であることを意味します。
mike23

回答:


30

クエリに可能な値の配列を入力する

データベースの値が文字列であり、クエリにいくつかの値をフィードする場合:

$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「トピック」が設定されているすべての投稿を取得し、それらを手動で繰り返すか、つまりループ内の値を確認し、その条件で投稿を表示することです。


14

Johannesの応答を無効にするには、シリアル化された配列であるため、ユーザーID(私の場合)のようなものを保存している場合、少し異なる方法で処理する必要があります。

投稿メタは次のように保存されていました:

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

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

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

したがって、実際には、探しているもののシリアル化された文字列バージョンとLIKE比較を行っています。私はこのようなものを機能させるためにかなりの時間を費やしました。


シリアル化(1)(strval)は、私の問題を解決してくれてありがとう
Behzad

今日、たまたまこの古い答えに出くわしました。あなたの追加が好きです。+1
ヨハネスポール

私もこれに遭遇しました、私のことは、user_idが配列にないすべての投稿を取得する必要があることですが、上記の解決策は機能しない'meta_query' => array( array( 'key' => 'my_meta_key', 'value' => ':' . $user_id . ';', 'compare' => 'NOT LIKE' ) ) ので、このようにしました: シリアル化するとすべての値が次のように保存されます: ' :値;'
ボブ

4

@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
)

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

最終結果は次のとおりです。

        '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がインデックスとして表示される場合、誰かがマテリアルに不正アクセスすることができます。したがって、問題が議論されている場合はこれが機能しますが、@ sMyles 'メソッドを代わりに使用できるように、検索する値を保存する前に文字列としてキャストすることを確認することをお勧めします。


これは、最も信頼性の高い選択答え、あるべき
Aminの

2

ヨハネスの答えに行きます。ただし、me​​ta_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を

$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'
            )
        )
    );

1

今日は似たようなものに苦労しました。複数の関連ユーザー(配列)を使用して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'
        ),
    )
);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.