query_posts -> folosind meta_compare / unde valoarea meta este mai mică, mai mare sau egală

22 sept. 2010, 23:18:01
Vizualizări: 30.7K
Voturi: 3

Folosesc query_posts( $args ) pentru a filtra Loop-ul. Vreau să filtrez postările bazate pe meta_value "vote", uneori mai mic decât, alteori egal și așa mai departe....

Vreau neapărat să folosesc funcția query_posts() și să transmit filtrul meu prin $args! Nu vreau să folosesc add_filter('posts_where', 'filter_where'); și apoi să adaug o instrucțiune AND la query.

Vreau să folosesc funcționalitatea oferită de WordPress pentru a filtra postările cu meta_key, meta_value și meta_compare astfel:

$args = array( 'meta_key'=>'vote', 'meta_compare'=>'>=', 'meta_value'=>5, 'posts_per_page'=>100 ) )

query_posts( $args );

Rezultatul acestuia este:

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND wp_postmeta.meta_key = 'vote' AND wp_postmeta.meta_value >= '5' GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 100

Problema este:

wp_postmeta.meta_value >= '5' 

Ar trebui să fie:

wp_postmeta.meta_value >= 5

Atunci ar funcționa bine.

Nu înțeleg de ce WordPress adaugă ghilimele.

Folosesc parametrul predefinit din WordPress (<, >, <=, >=) și este evident că acesta va funcționa doar cu numere și nu cu șiruri care ar trebui să fie între ghilimele.

Documentația spune:

Returnează postări cu cheia câmpului personalizat 'miles' cu o valoare a câmpului personalizat care este MAI MICĂ SAU EGALĂ CU 22

query_posts('meta_key=miles&meta_compare=<=&meta_value=22');

0
Toate răspunsurile la întrebare 4
2
12

Începând cu WP 3.1, puteți converti valoarea meta în orice doriți folosind argumentul 'type' în 'meta_query':

$args = array(
  'meta_query'=> array(
    array(
      'key' => 'vote',
      'compare' => '>=',
      'value' => 5,
      'type' => 'numeric',
    )
  )
  'posts_per_page' => 100
) );

query_posts( $args );
16 mar. 2011 17:57:40
Comentarii

Acesta este un răspuns excelent - rezolvă complet problema.

Samuel Hulick Samuel Hulick
23 oct. 2011 14:24:21

''type' => 'numeric',' a rezolvat problema mea Dar mă îndoiesc că nu ar trebui să conțină virgulă

vaibhav vaibhav
2 ian. 2013 19:36:49
1

După o scurtă privire peste documentație, se pare că meta_value este destinat pentru șiruri de caractere, iar pentru valori numerice există meta_value_num.

Vezi Parametrii Orderby

Actualizare

Am investigat mai detaliat.

meta_value_num este într-adevăr ignorat în scopul filtrării. Cred că pur și simplu au uitat să adauge acea parte. :)

Problema este că WP_Query primește corect numărul ca int (transmiterea ca array nu contează), dar trece condiția generată meta_compare prin $wpdb->prepare() și marchează explicit valoarea ca șir %s. În acest caz, prepare o pune între ghilimele simple.

Deci se pare că va trebui să filtrezi posts_where până la urmă. Poți încerca să elimini ghilimelele din acel șir specific, în loc să generezi condiția manual.

22 sept. 2010 23:31:57
Comentarii

această utilizare este destinată doar pentru sortarea datelor... dar am încercat-o și nu funcționează. Când am văzut răspunsul tău, m-am gândit că asta e soluția....

User User
22 sept. 2010 23:37:29
6

Vă recomand să analizați array-ul $args și să îl convertiți într-un șir înainte de a-l transmite în query_posts. Când creați array-ul $args, sistemul va converti automat numărul 5 în șirul "5" atunci când array-ul este transformat înapoi într-un șir.

Deci, folosiți această variantă:

query_posts('meta_key=vote&meta_compare=>=&meta_value=5&posts_per_page=100');

Aceasta transmite aceleași informații către query_posts, dar ar trebui să transmită numărul 5 în loc de șirul "5".


Actualizare

Deoarece am descoperit acum că meta_value stochează șiruri în loc de numere și nu puteți efectua în mod eficient o comparație de tip mai mare/mai mic cu șiruri. Cu toate acestea, după câteva cercetări suplimentare, am dat peste flag-ul de interogare meta_value_num.

Dacă executați următorul apel query_posts:

query_posts('meta_key=vote&meta_compare=>=&meta_value=5&posts_per_page=100&orderby=meta_value_num');

Atunci ar trebui să obțineți comportamentul dorit. meta_value_num instruiește WordPress să evalueze valorile meta_value ca numere în loc de șiruri.

22 sept. 2010 23:29:24
Comentarii

Am încercat și produce exact același lucru. De fapt, am urmărit calea de la funcție la funcție în WordPress-Core și șirul este separat la & și transformat într-un array înainte de a fi procesat....

User User
22 sept. 2010 23:33:55

Conform Codex: Notă: valoarea 99 va fi considerată mai mare decât 100, deoarece datele sunt stocate ca șiruri de caractere, nu ca numere. Deci meta_value este stocat ca șir de caractere... motiv pentru care WordPress adaugă ghilimele. Următoarea mea întrebare ar fi, poți descrie cum "nu funcționează"? Returnează vreun date deloc?

EAMann EAMann
22 sept. 2010 23:47:45

Da, ai dreptate! Cum am spus mai sus, indiferent ce fac, este încapsulat în '5'. MySQL nu poate compara ceva la nivel numeric dacă este încapsulat în '', așa că mă întreb de ce WordPress a implementat această funcție dacă nu funcționează. Nu, returnează rezultate, dar nu cele dorite.

User User
22 sept. 2010 23:50:38

Vezi actualizarea mea de mai sus. Adăugarea orderby=meta_value_num ar trebui să rezolve problema dacă folosești WP 2.8.4 sau o versiune mai recentă.

EAMann EAMann
23 sept. 2010 00:12:55

Mulțumesc pentru toate eforturile. Dar nici asta nu funcționează. Am cercetat temă în profunzime și pur și simplu nu este suportat de WP. Voi crea un ticket pentru această problemă pentru că este foarte ușor de rezolvat și ar face multe lucruri posibile!

User User
23 sept. 2010 21:31:34

@Joakim Da, această funcționalitate este suportată de WP. Citește ticket-ul pe care l-am menționat mai sus unde a fost adăugată această caracteristică. Poate ne poți oferi un exemplu mai mare de cod pentru ceea ce încerci să faci... ar putea fi o altă problemă.

EAMann EAMann
23 sept. 2010 22:05:47
Arată celelalte 1 comentarii
0

WordPress tratează toate valorile 'value' ca șiruri de caractere și le adaugă ghilimele simple în interogarea finală, așa că SQL este forțat să le considere ca șiruri și nu ca numere. Puteți elimina aceste ghilimele cu un filtru:

add_filter('get_meta_sql', function($data) {
  $regex = "/'(-?\d+)'/";
  $data['where'] = preg_replace($regex, "$1", $data['where']);
  return $data;
});

Și asigurați-vă că aveți 'type' => 'NUMERIC' sau similar

7 feb. 2025 18:42:35