Interogarea tuturor articolelor unde nu există o cheie meta

12 ian. 2013, 18:48:33
Vizualizări: 109K
Voturi: 70

Încerc să obțin o interogare care să recupereze toate articolele unde o anumită meta_key nu există și apoi să o creez.

Am probleme în găsirea acestor articole deoarece interogarea pe care o testez nu pare să funcționeze.

Iată codul pe care îl folosesc pentru a încerca să obțin aceste articole:

$args = array(
   'posts_per_page' => 18,
   'cat'=>1955,
   'post_status'=>'publish',
   'meta_query' => array(
                  array(
                     'key' => 'colors',
                     'compare' => 'NOT EXISTS'
                  ),
   ));      

query_posts($args);

Aceasta nu returnează nimic dacă nu există articole cu cheia colors, dar returnează ids-urile articolelor cu cheia colors ori de câte ori această cheie este prezentă (opusul a ceea ce am nevoie). Am încercat cu EXIST în loc, dar fără succes.

Dacă cineva mă poate îndruma cu privire la modul corect de a crea o interogare precum cea de care am nevoie, voi aprecia.

Mulțumesc!

7
Comentarii

Ce versiune de WordPress folosești?

s_ha_dum s_ha_dum
12 ian. 2013 19:10:08

Bună, îmi cer scuze pentru omisiune. Folosesc versiunea 3.5

JordanBel JordanBel
12 ian. 2013 20:27:19

Se pare că acest tip de interogare (cu compare setat la NOT EXISTS) a fost adăugat în versiunea 3.5, așa că ar trebui să funcționeze așa cum este, din câte văd. Totuși, ar fi ușor de implementat folosind o interogare SELECT personalizată...

Tomas Buteler Tomas Buteler
12 ian. 2013 22:00:37

Mulțumesc, voi încerca să folosesc SELECT. Trebuie mai întâi să învăț ce tabele să interoghez și cum să structurez interogarea totuși :(

JordanBel JordanBel
12 ian. 2013 23:08:34

Foarte ciudat. Nu văd nicio problemă cu acel cod și folosești versiunea 3.5+, de aceea am întrebat. Ai verificat efectiv baza de date pentru a confirma că datele sunt inserate așa cum crezi?

s_ha_dum s_ha_dum
13 ian. 2013 19:07:02

Ai încercat 'EXISTS'? Ai menționat 'EXIST' dar cred că compare acceptă doar 'EXISTS' cu un 'S' la final.

mikegertrudes mikegertrudes
13 ian. 2013 22:36:10

Bună, mulțumesc. Din păcate, EXISTS nu a funcționat nici el. Cred că voi merge pe opțiunea cu query.

JordanBel JordanBel
14 ian. 2013 03:01:41
Arată celelalte 2 comentarii
Toate răspunsurile la întrebare 3
8
108

Am făcut mai multe teste cu asta și sincer nu pot găsi un motiv pentru care nu ar funcționa (decât dacă codul de mai sus este doar un fragment și codul real se potrivește cu exemplele mele de mai jos). Totuși, am descoperit câteva lucruri care ar putea să vă indice direcția corectă.

1) În sine, această interogare meta este echivalentul cu "colors IS NULL", adică va returna postările care nu au acea cheie setată în tabelul postmeta. Acesta este cazul prezentat mai sus și ar fi trebuit să funcționeze.

'meta_query' => array(
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // acesta ar trebui să funcționeze...
    ),
)

2) Înainte de WordPress 3.9, stabilirea indexului 'relation' la 'OR' schimbă această condiție. Returnează opusul. Nu mă întrebați de ce. Acest lucru este deosebit de important atunci când faceți mai multe interogări meta. Asta înseamnă că inițial nu este posibil să faceți o interogare pentru postări care au cheia 'colors' setată la 'blue' (sau orice altceva) sau nesetată deloc. Interogarea de mai jos va ignora prima condiție și va returna doar cele care se potrivesc cu a doua condiție.

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // nu funcționează
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

3) Totuși, putem păcăli WordPress să folosească prima condiție dacă setăm 'value'. Nu are nevoie de o valoare relevantă (este ignorată, din câte știu), dar trebuie să fie setată pentru ca condiția NOT EXISTS să aibă vreun efect.

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS', // funcționează!
     'value' => '' // Aceasta este ignorată, dar este necesară...
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

Aceasta a fost valabilă până la WordPress 3.9. Dacă încă folosiți o versiune mai veche, aceasta este o soluție viabilă.

16 ian. 2013 17:05:16
Comentarii

Mulțumesc! Și îmi cer scuze pentru întârziere. Am ajuns să folosesc o interogare, dar voi testa soluția ta în următoarele ore, astfel încât să pot reveni și, dacă funcționează, poate vom putea ajuta și pe alții. Te voi anunța imediat ce o pot verifica. Mulțumesc din nou

JordanBel JordanBel
17 ian. 2013 03:49:32

Foarte bine scris și confirmat că adăugarea unei valori goale returnează rezultatele așteptate. Aș spune că este neintenționat, ar merita să arunci o privire pe trac.wordpress.org pentru a vedea dacă există deja un tichet, dacă nu, acest lucru este reproducibil.

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

Mulțumesc pentru explicația excelentă și soluția de a păcăli WP :) Mi-a luat ceva timp să ajung aici - dar acum vreau să dau upvote de cel puțin 10 ori (dacă aș putea ;))

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

Dacă folosesc comparația EXISTS, valoarea nu este ignorată din păcate în versiunile mai noi de WP (testat în 4.2.2)

Igor Jerosimić Igor Jerosimić
1 iul. 2015 13:08:45

Atenție la orderby meta_key care poate fi și el în interogarea ta! WordPress va introduce direct WHERE meta_key = value și pentru o ordonare după meta!

Chizzle Chizzle
8 apr. 2016 06:12:57

"Bug-ul" EXISTS și NOT EXISTS care te obliga să specifici o valoare, a fost rezolvat în WP 3.9

trex005 trex005
15 apr. 2016 10:42:22

trex005 are dreptate: "(Notă: Din cauza bug-ului #23268, valoarea este obligatorie pentru ca comparațiile NOT EXISTS să funcționeze corect înainte de versiunea 3.9. Trebuie să furnizați un șir de caractere pentru parametrul value. Un șir gol sau NULL NU va funcționa. Totuși, orice alt șir de caractere va face treaba și NU va apărea în interogarea SQL atunci când utilizați NOT EXISTS. Ai nevoie de inspirație? Ce zici de 'bug #23268'.)"

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

Combinația 'OR' așa cum este arătat mai sus la punctul 3) funcționează și pentru mine, dar este foarte ineficientă și duce la timpi de încărcare mari, peste 30 de secunde. (folosind Woocommerce cu peste 9000 de produse)

Andy Tschiersch Andy Tschiersch
6 oct. 2021 14:22:12
Arată celelalte 3 comentarii
0
20

Folosind o interogare personalizată, aceasta a funcționat pentru mine:

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

Adăugarea unei relații face să funcționeze, chiar dacă există o singură clauză

'meta_query' => array(
   'relation' => 'OR', // relație între condiții
    array(
     'key' => 'colors', // cheia meta
     'compare' => 'NOT EXISTS' // comparație - inexistență
    )
)
9 ian. 2020 12:49:34