Query di tutti i post dove una chiave meta non esiste
Sto cercando di ottenere una query per recuperare tutti i post dove una specifica meta_key
non esiste per poi crearla.
Sto avendo problemi a trovare quei post poiché la query che sto testando non sembra funzionare.
Ecco il codice che sto usando per provare a ottenere quei post:
$args = array(
'posts_per_page' => 18,
'cat'=>1955,
'post_status'=>'publish',
'meta_query' => array(
array(
'key' => 'colors',
'compare' => 'NOT EXISTS'
),
));
query_posts($args);
Questo non restituisce nulla se non ci sono post con la chiave colors
, ma restituisce gli ids
dei post con la chiave colors
quando quella chiave è presente (l'opposto di quello che mi serve). Ho provato con EXIST
invece ma senza successo.
Se qualcuno può darmi un suggerimento sul modo corretto di creare una query come quella di cui ho bisogno lo apprezzerei molto.
Grazie!

Ho eseguito ulteriori test su questo argomento e onestamente non riesco a trovare un motivo per cui non dovrebbe funzionare (a meno che il codice sopra non sia solo un frammento e il codice reale rientri nei miei esempi seguenti). Tuttavia, ho scoperto un paio di cose che potrebbero indirizzarvi nella giusta direzione.
1) Di per sé, questa meta query è equivalente a "colors IS NULL", cioè restituirà i post che non hanno questa chiave impostata nella tabella postmeta. Questo è il caso mostrato sopra e avrebbe dovuto funzionare.
'meta_query' => array(
array(
'key' => 'colors',
'compare' => 'NOT EXISTS' // questo dovrebbe funzionare...
),
)
2) Prima di WordPress 3.9, stabilire l'indice 'relation' su 'OR' cambia questa condizione. Restituisce l'opposto. Non chiedetemi perché. Questo è particolarmente importante quando si eseguono più meta query. Ciò significa che inizialmente non è possibile eseguire una query per i post che hanno la chiave 'colors' impostata su 'blue' (o qualsiasi altro valore) o non impostata affatto. La query seguente ignorerà la prima condizione e restituirà solo quelli che corrispondono alla seconda condizione.
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'colors',
'compare' => 'NOT EXISTS' // non funziona
),
array(
'key' => 'colors',
'value' => 'blue'
)
)
3) Tuttavia, possiamo ingannare WordPress per utilizzare la prima condizione se impostiamo il 'value'. Non ha bisogno di un valore rilevante (viene ignorato, per quanto ne so), ma deve essere impostato affinché la condizione NOT EXISTS
abbia effetto.
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'colors',
'compare' => 'NOT EXISTS', // funziona!
'value' => '' // Questo viene ignorato, ma è necessario...
),
array(
'key' => 'colors',
'value' => 'blue'
)
)
Questo era vero fino a WordPress 3.9. Se state ancora utilizzando una versione più vecchia, questo è un valido workaround.

Grazie! E scusa per il ritardo. Alla fine ho usato una query, ma testerò la tua soluzione nelle prossime ore così potrò tornare indietro e magari se funziona possiamo aiutare qualcun altro. Ti farò sapere appena posso verificare. Grazie ancora

Ben scritto e confermato che aggiungere un valore vuoto restituisce i risultati attesi. Direi che è involontario, potrebbe valere la pena dare un'occhiata su trac.wordpress.org per vedere se c'è già un ticket, altrimenti questo è riproducibile.

Grazie per la splendida spiegazione e la soluzione per aggirare WP :) Ci ho messo un po' ad arrivare qui - ma ora vorrei cliccare su upvote almeno 10 volte (se solo potessi ;))

Se utilizzo EXISTS per il confronto, il valore purtroppo non viene ignorato nelle versioni più recenti di WP (testato in 4.2.2)

Attenzione a un eventuale orderby meta_key
che potrebbe essere presente nella tua query! WordPress codificherà in modo rigido WHERE meta_key = value
anche per un orderby basato su meta!

Il "bug" di EXISTS
e NOT EXISTS
che richiedeva di specificare un valore è stato risolto in WP 3.9

trex005 ha ragione: "(Nota: A causa del bug #23268, il valore è obbligatorio affinché i confronti NOT EXISTS funzionino correttamente prima della versione 3.9. È necessario fornire una stringa per il parametro value. Una stringa vuota o NULL NON funzionerà. Tuttavia, qualsiasi altra stringa andrà bene e NON comparirà nel tuo SQL quando usi NOT EXISTS. Ti serve ispirazione? Che ne dici di 'bug #23268'.)"
