Query di tutti i post dove una chiave meta non esiste

12 gen 2013, 18:48:33
Visualizzazioni: 109K
Voti: 70

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!

7
Commenti

Che versione di WordPress stai utilizzando?

s_ha_dum s_ha_dum
12 gen 2013 19:10:08

Ciao, scusa per l'omissione. Sto utilizzando la versione 3.5

JordanBel JordanBel
12 gen 2013 20:27:19

Sembra che quel tipo di query (con compare impostato a NOT EXISTS) sia stato aggiunto nella 3.5, quindi dovrebbe funzionare così com'è, per quanto posso vedere. Sarebbe comunque facile farlo tramite una query SELECT personalizzata...

Tomas Buteler Tomas Buteler
12 gen 2013 22:00:37

Grazie, proverò a usare select. Prima però devo imparare quali tabelle interrogare e come strutturare la query :(

JordanBel JordanBel
12 gen 2013 23:08:34

Molto strano. Non riesco a individuare un problema con quel codice e stai usando la 3.5+, motivo per cui ho chiesto. Hai effettivamente controllato il database per confermare che i tuoi dati vengano inseriti nel modo in cui pensi?

s_ha_dum s_ha_dum
13 gen 2013 19:07:02

Hai provato 'EXISTS'? Hai menzionato 'EXIST' ma credo che compare accetti solo 'EXISTS' con una 'S' alla fine.

mikegertrudes mikegertrudes
13 gen 2013 22:36:10

Ciao, grazie. Purtroppo anche EXISTS non ha funzionato. Penso che opterò per la soluzione con la query.

JordanBel JordanBel
14 gen 2013 03:01:41
Mostra i restanti 2 commenti
Tutte le risposte alla domanda 3
8
108

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.

16 gen 2013 17:05:16
Commenti

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

JordanBel JordanBel
17 gen 2013 03:49:32

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.

Taylor Dewey Taylor Dewey
6 mar 2013 21:22:07

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

lorem monkey lorem monkey
21 mar 2013 16:18:41

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

Igor Jerosimić Igor Jerosimić
1 lug 2015 13:08:45

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!

Chizzle Chizzle
8 apr 2016 06:12:57

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

trex005 trex005
15 apr 2016 10:42:22

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'.)"

jave.web jave.web
29 apr 2017 22:56:11

La combinazione 'OR' mostrata sopra al punto 3) funziona anche per me, ma è molto inefficiente e risulta in tempi di caricamento pesanti superiori ai 30 secondi. (utilizzando Woocommerce con più di 9000 prodotti)

Andy Tschiersch Andy Tschiersch
6 ott 2021 14:22:12
Mostra i restanti 3 commenti
0
20

Utilizzando una query personalizzata, questa ha funzionato per me:

SELECT * FROM wp_posts as posts
            WHERE   posts.post_type     = 'post'
            AND NOT EXISTS (
              SELECT * FROM `wp_postmeta`
               WHERE `wp_postmeta`.`meta_key` = "your_meta_key"
                AND `wp_postmeta`.`post_id`=posts.ID
            ) 
9 gen 2015 23:50:35
0

Aggiungere una relazione fa funzionare il tutto, anche se c'è solo una clausola

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' 
    )
)
9 gen 2020 12:49:34