Come posso creare una meta_query con un array come meta_field?


16

Ecco gli argomenti per la mia query:

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

Funziona quando topicsè una stringa, ma non quando è una matrice. Vorrei che questa query funzionasse quando topicsè per esempioarray( 'sports', 'nonprofit', etc. )

Esiste un modo per creare meta query con array come meta_key?


Si prega di chiarire: vuoi dire che il valore memorizzato di "argomenti" è un array? O che il valore memorizzato è una stringa e si desidera passare più termini alla query in un array?
MathSmath,

@MathSmath, intendo che il valore memorizzato è un array.
mike23,

Risposte:


31

Alimentando la query una matrice di possibili valori

Se il valore nel database è una stringa e si desidera alimentare alla query diversi valori:

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

Ricerca di un valore specifico in una matrice di dati serializzata

Se il valore nel database è un array di più argomenti e si desidera cercare un singolo argomento all'interno di tale array (si noti che un array nel database può essere recuperato come tale, ma risiede nel database in forma serializzata, che è un stringa anche):

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

L'uso di "MI PIACE" come valore di confronto non è un'istruzione così chiara come avresti potuto sperare, ma è l'opzione migliore da seguire.

Accanto a ciò, l'unica altra opzione sarebbe recuperare tutti i post che hanno impostato gli "argomenti" meta_key e iterarli manualmente o, in altre parole, verificare il valore all'interno del loop e visualizzare i post in detta condizione.


14

Per uscire dalla risposta di Johannes, poiché si tratta di un array serializzato, se ti capita di archiviare qualcosa come l'id utente (che era il mio caso), potresti doverlo gestire in modo leggermente diverso.

Post meta è stato salvato come:

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

Quindi sì, sono numeri interi ma attraverso update_post_metasono stati salvati come stringhe.

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

Quindi stai effettivamente facendo un confronto LIKE con la versione di stringa serializzata di ciò che stai cercando. Ho trascorso un paio d'ore cercando di far funzionare qualcosa del genere e finora questo è stato il migliore che ho potuto inventare.


serialize (strval (1)) risolto il mio problema, grazie
Behzad,

Oggi ho incontrato questa vecchia risposta per caso. Mi piace la tua aggiunta. +1
Johannes Pille,

Mi sono appena imbattuto anche in questo, la mia cosa è che ho bisogno di ottenere tutti i post in cui user_id non è in array, ma la soluzione sopra non funziona quindi l'ho fatto così: 'meta_query' => array( array( 'key' => 'my_meta_key', 'value' => ':' . $user_id . ';', 'compare' => 'NOT LIKE' ) ) Perché quando serializzato tutti i valori vengono salvati come: ' :valore;'
Bobz,

4

Un altro leggero miglioramento dalla risposta di @sMyles.

Ho avuto casi in cui gli ID sono stati memorizzati sia come stringhe (come quando presi da un input di modulo) sia come numeri interi (ad es update_post_meta($post_id, authorized_users', array(get_current_user_id()));.). Questo è un po 'come il noto problema con wp_set_object_terms()cui è possibile utilizzare gli ID termine per impostare i termini, ma se non li si lancia come numeri primi si ha una probabilità del 50% di creare nuovi termini con quei numeri come nomi anziché.

Ciò può comportare che vengano archiviati in modo piuttosto diverso in un array serializzato, come si può vedere dagli estratti di un caso del genere dal database del mio sito di test:

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

Entrambi i precedenti, quando alimentati print_r()renderanno come

Array
(
    [0] => 1
)

Per risolvere questo problema, ho apportato una leggera modifica meta_queryall'aggiunta di una relatione un'altra versione della query che ha lanciato il valore come numero intero anziché come stringa.

Ecco il risultato finale:

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

EDIT: Ho appena realizzato che questo metodo potrebbe correre il rischio di collisioni con indici di array, il che potrebbe consentire a qualcuno di accedere illecitamente ai materiali se non sono nell'array, ma il loro ID utente appare come un indice. Pertanto, mentre questo funziona se si discute del problema, è consigliabile assicurarsi che tutti i valori che si desidera cercare vengano sottoposti a cast come stringhe prima di salvarli in modo da poter utilizzare invece il metodo @sMyles.


Questa dovrebbe essere la risposta selezionata, la più affidabile
Amin,

2

Vorrei la risposta di Johannes. Tuttavia, voglio migliorarlo perché usando quella meta_query, incontrerai un caso come questo

il tuo valore è

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

quando cerchi

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

quindi il risultato restituirà "sport" e "sport2".

Per risolvere il problema, modifica gli argomenti meta_query in

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

È perché il valore è serializzato nel database e ogni elemento sarà separato da un punto e virgola. Quindi, sopra args funzionerà

Se gli articoli nel valore sono numeri, devi solo rimuovere la doppia virgoletta "

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

1

Ho lottato con qualcosa di simile oggi. Devo interrogare un campo di relazione ACF (Advanced Custom Fields) con più utenti correlati (array).

Dopo aver aggiornato il campo tramite php la query non ha funzionato. Dopo averlo aggiornato tramite l'interfaccia utente ACF, la query ha funzionato.

Il problema era che il mio codice php impostava i valori della relazione come valori int, l'interfaccia utente lo impostava su valori stringa. Per essere sicuro che entrambi funzionino, ora uso questa query (adattata all'esempio qui):

$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'
        ),
    )
);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.