LIKE %...% Meta Query pentru array serializat
Am un array serializat ca valoare meta și încerc să execut un WP Query care să găsească o valoare specifică în array-ul serializat.
Iată un exemplu al câmpului array serializat:
a:6:{i:0;s:3:"173";i:1;s:3:"172";i:2;s:3:"171";i:3...
Iată query-ul meu, dar nu funcționează: ID-urile pentru care fac căutarea sunt numerice.
$practiceArgs = array(
'post_type' => 'attorney',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'practice_area',
'value' => $post->ID,
'compare' => 'LIKE',
'type' => 'NUMERIC'
)
)
);
Am încercat să folosesc 'value' => '%'.$post->ID.'%'
în query-urile mele, dar pare că nu funcționează nici așa.
A mai avut cineva experiență în lucrul cu acest tip de interogare?

Am întâlnit aceeași problemă astăzi. În ambele situații, există de fapt o soluție elegantă. Deoarece datele serializate pe care le căutăm sunt pur și simplu ID-uri și sunt întotdeauna încadrate între ghilimele, trebuie doar să includem ghilimelele ca parte a interogării. Acest lucru elimină problema apariției de rezultate false în căutare.
Trebuie doar să modificați interogarea meta astfel:
array(
'key' => 'practice_area',
'value' => '"'.$post->ID.'"',
'compare' => 'LIKE',
)
În acest fel, se caută întregul ID, inclusiv ghilimelele duble dinaintea și de după acesta în cadrul tabloului serializat. Nu vor fi incluse rezultate false.

Am întâlnit această problemă odată, dar cu siguranță nu este o situație plăcută. Modul în care abordezi acest lucru va face ca rezultatul să nu fie niciodată consistent - căutarea ta va returna multe rezultate false pozitive (de exemplu, căutând ID-ul postării 43 va returna 143, 243, 1431, 1432, etc.).
Din punctul meu de vedere, ai două opțiuni:
- Reanalizează modul în care salvezi metadatele; folosește array-uri pentru datele
care sunt necesare doar la afișarea postării, dar nu și pentru datele pe care trebuie să le interoghezi pentru a filtra postările. Pentru acestea din urmă, folosește chei meta individuale în baza de date - este mult mai rapid, interogările sunt mai ușor de codat, și poți fi sigur că vei avea control total asupra a ceea ce returnează interogările. Nu-ți face griji că folosești prea multe rânduri în tabelul postmeta: tocmai de aceea există. - Dacă din anumite motive trebuie să ai mai multe câmpuri într-un singur rând din baza de date,
nu te baza pe serializarea implicită: folosește CSV, de preferință cu un fel de prefix, ceva care nu va returna rezultate false pozitive. Ceva de genul"id:43,id:54,foo:bar,id:57,"
, apoi caută 'id:{post_ID},
' (reține că toate valorile trebuie să se termine cu virgule pentru a putea folosi în siguranță wildcard-uri duble într-o căutare LIKE. Este un fel de hack, dar este mai sigur decât ceea ce încerci acum.
Pentru ceea ce valorează, referitor la întrebarea inițială, WP deja adaugă ambele wildcard-uri când face comparații LIKE folosind query_posts
, deci nu trebuie să faci nimic.

LIKE-ul din WordPress nu este același cu LIKE-ul din MySQL, așadar 'value' => '%'.$post-ID.'%' nu funcționează.
Puteți încerca varianta cu REGEXP. De exemplu:
'meta_query' => array(
array(
'key' => 'attorney',
'value' => '^'.$post-ID,
'compare' => 'REGEXP',
)
)
Aceasta ar trebui să caute toate elementele unde câmpul attorney începe cu valoarea din $post-ID.

Nu poți folosi LIKE
cu numeric
(cel puțin sunt destul de sigur că nu poți). numeric
va încerca să convertească întreaga valoare
la un număr. Asta va eșua, deoarece nu este un număr. Aceasta este prima greșeală.
În al doilea rând, pentru a obține un caracter literal %
, trebuie să-l dublezi la %%
. Notă: Nu îmi amintesc exact pentru meta_query
strict vorbind. Extrapolez din ceea ce este necesar pentru a trece un %
prin $wpdb->prepare
. Cred că este același lucru însă. Edit: Se pare că asta este valabil doar pentru $wpdb->prepare
. Codul a fost actualizat.
Nu am testat acest lucru, deoarece ar trebui să configurez câteva lucruri în baza mea de date și nu am timp acum, dar cred că va funcționa.
$practiceArgs = array(
'post_type' => 'attorney',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'practice_area',
'value' => $post->ID,
'compare' => 'LIKE'
)
)
);
Sper că aceasta este îndemnul de care ai nevoie. Dacă nu funcționează, voi reveni.
Edit: Am introdus array-ul tău serializat (defect) în baza mea de date și am rulat codul de mai sus. Dacă am configurat totul corect— meta_câmpurile, tipurile de postări, etc.— codul de mai sus funcționează. Dacă nu funcționează pentru tine, este altceva în neregulă— poate crezi că ar trebui să existe o potrivire unde nu există.
Presupun că vei avea un array similar pentru fiecare dintre postările tale de tip 'attorney'. Dacă da, ar trebui să funcționeze. Aș putea prefera mai multe rânduri practice_area
în loc să folosești un array serializat. =
este o interogare mai eficientă decât LIKE
, mai ales când ai wildcard-uri, iar rezultatele ar trebui să fie mai precise. Indexarea (baza de date MySQL) ar funcționa și ea mai bine.

Comentariul tău referitor la '%' este valabil doar când folosești $wpdb->prepare. Când folosești query_posts, utilizarea '%' este inutilă: WP le adaugă automat, indiferent dacă dorești sau nu.
