it-swarm.com.de

Wie kann ich eine meta_query mit einem Array als meta_field erstellen?

Hier sind die Argumente für meine Anfrage:

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

Dies funktioniert, wenn topics eine Zeichenfolge ist, aber nicht , wenn es sich um ein Array handelt. Ich möchte, dass diese Abfrage funktioniert, wenn topics beispielsweise array( 'sports', 'nonprofit', etc. ) ist.

Gibt es eine Möglichkeit, Metaabfragen mit Arrays als meta_key zu erstellen?

13
mike23

Füttert die Abfrage mit einem Array möglicher Werte

Wenn der Wert in der Datenbank eine Zeichenfolge ist und Sie der Abfrage mehrere Werte hinzufügen möchten:

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

Suchen nach einem bestimmten Wert in einem serialisierten Datenfeld

Wenn der Wert in der Datenbank ein Array mit mehreren Themen ist und Sie nach einem einzelnen Thema in diesem Array suchen möchten (Beachten Sie, dass ein Array in der Datenbank als solches abgerufen werden kann, sich jedoch in der Datenbank in serialisierter Form befindet, d. H Zeichenfolge auch):

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

Die Verwendung von 'LIKE' als Vergleichswert ist nicht so eindeutig, wie Sie es sich erhofft haben, aber die beste Option.

Daneben besteht Ihre einzige andere Möglichkeit darin, alle Posts abzurufen, für die meta_key "topics" festgelegt ist, und sie manuell zu durchlaufen, oder mit anderen Worten, den Wert in der Schleife zu überprüfen und die Posts unter dieser Bedingung anzuzeigen .

27
Johannes Pille

Um von Johannes 'Antwort abzuweichen, da es sich um ein serialisiertes Array handelt, müssen Sie möglicherweise etwas anders damit umgehen, wenn Sie etwas wie Benutzer-IDs speichern (was in meinem Fall der Fall war).

Post-Meta wurde gespeichert wie:

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

Also ja, sie sind ganze Zahlen, aber durch update_post_meta wurden sie als Zeichenfolgen gespeichert.

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

Sie führen also tatsächlich einen LIKE-Vergleich mit der serialisierten String-Version des gesuchten Elements durch. Ich habe ein paar gute Stunden damit verbracht, so etwas zum Laufen zu bringen, und bisher war dies das Beste, was ich mir einfallen lassen konnte.

12
sMyles

Eine weitere leichte Verbesserung gegenüber der Antwort von @sMyles.

Ich hatte Fälle, in denen IDs sowohl als Zeichenfolgen (z. B. aus einer Formulareingabe) als auch als Ganzzahlen (z. B. update_post_meta($post_id, authorized_users', array(get_current_user_id()));) gespeichert wurden. Dies ähnelt dem bekannten Problem mit wp_set_object_terms(), bei dem Sie Term-IDs verwenden können, um die Termini festzulegen. Wenn Sie sie jedoch nicht zuerst als Ganzzahlen umwandeln, haben Sie eine Chance von etwa 50%, neue Termini mit diesen Zahlen zu erstellen Namen statt.

Dies kann dazu führen, dass sie in einem serialisierten Array ganz anders gespeichert werden, wie aus den Auszügen eines solchen Falls aus der Datenbank meiner Testwebsite ersichtlich ist:

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

Beide der oben genannten Optionen werden bei Durchleitung von print_r() als gerendert

Array
(
    [0] => 1
)

Um dies zu beheben, habe ich den meta_query leicht angepasst, indem ich eine relation und eine andere Version der Abfrage hinzugefügt habe, die den Wert als Ganzzahl anstelle einer Zeichenfolge umwandelt.

Hier ist das Endergebnis:

        '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'
            ),
        ),

BEARBEITEN: Gerade wurde erkannt, dass diese Methode das Risiko von Kollisionen mit Array-Indizes birgt, die jemandem den unerlaubten Zugriff auf Materialien ermöglichen könnten, wenn er nicht im Array ist, aber seine Benutzer-ID als Index angezeigt wird. Während dies funktioniert ist, sollten Sie sicherstellen, dass alle zu suchenden Werte vor dem Speichern als Zeichenfolgen umgewandelt werden, damit Sie stattdessen die @ sMyles-Methode verwenden können .

3
Kaji

Ich würde Johannes 'Antwort annehmen. Ich möchte dies jedoch verbessern, da Sie mit dieser meta_query einen Fall wie diesen treffen werden

ihr Wert ist

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

wenn du suchst

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

dann wird das Ergebnis sowohl 'sport' als auch 'sport2' zurückgeben.

Um dies zu beheben, ändern Sie die Argumente für meta_query in

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

Dies liegt daran, dass der Wert in der Datenbank serialisiert ist und jedes Element durch ein Semikolon getrennt wird. Daher funktionieren die obigen Argumente

Wenn es sich bei den Elementen im Wert um Zahlen handelt, müssen Sie nur das doppelte Anführungszeichen entfernen. "

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

Ich habe heute mit etwas Ähnlichem gekämpft. Ich muss ein ACF-Beziehungsfeld (Advanced Custom Fields) mit mehreren verbundenen Benutzern (Array) abfragen.

Nach der Aktualisierung des Feldes über PHP funktionierte die Abfrage nicht. Nach dem Update über die ACF-Benutzeroberfläche funktionierte die Abfrage.

Das Problem war, dass mein PHP-Code die Beziehungswerte auf int-Werte und die Benutzeroberfläche auf string-Werte setzte. Um sicherzustellen, dass beide funktionieren, verwende ich diese Abfrage jetzt (hier im Beispiel):

$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