query_posts -> utilizzare meta_compare / dove il valore meta è minore, maggiore o uguale

22 set 2010, 23:18:01
Visualizzazioni: 30.7K
Voti: 3

Sto usando query_posts( $args ) per filtrare il Loop. Voglio filtrare i post in base al loro meta_value "vote", a volte minore di, a volte uguale e così via...

Voglio assolutamente utilizzare la funzione query_posts() e passare il mio filtro attraverso $args! Non voglio usare add_filter('posts_where', 'filter_where'); e poi aggiungere un'istruzione AND alla query.

Voglio utilizzare la funzionalità predefinita di WordPress per filtrare i post con meta_key, meta_value e meta_compare in questo modo:

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

query_posts( $args );

Il risultato di questo è:

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

Il problema è questo:

wp_postmeta.meta_value >= '5' 

Dovrebbe essere:

wp_postmeta.meta_value >= 5

A questo punto funzionerebbe correttamente.

Non capisco perché WordPress aggiunge le virgolette.

Sto usando i parametri predefiniti di WordPress (<, >, <=, >=) ed è ovvio che questo funzionerà solo con i numeri e non con le stringhe che avrebbero bisogno delle virgolette.

La documentazione dice:

Restituisce i post con chiave del campo personalizzato 'miles' con un valore del campo personalizzato che è MINORE O UGUALE A 22

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

0
Tutte le risposte alla domanda 4
2
12

Da WP 3.1, puoi convertire il valore meta in qualsiasi cosa desideri utilizzando l'argomento 'type' in '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
Commenti

Questa è un'ottima risposta - funziona perfettamente.

Samuel Hulick Samuel Hulick
23 ott 2011 14:24:21

''type' => 'numeric',' ha risolto il mio problema Ma dubito che non dovrebbe contenere virgole

vaibhav vaibhav
2 gen 2013 19:36:49
1

Dando un'occhiata veloce alla documentazione, sembra che meta_value sia destinato alle stringhe e per i valori numerici c'è meta_value_num.

Vedi Parametri Orderby

Aggiornamento

Ho fatto alcune ricerche.

meta_value_num viene effettivamente ignorato per il filtraggio. Penso che si siano semplicemente dimenticati di aggiungere quella parte. :)

Il problema è che WP_Query riceve correttamente il numero come int (passarlo come array non cambia), ma passa la condizione generata meta_compare attraverso $wpdb->prepare() e contrassegna esplicitamente il valore come stringa %s. In questo caso prepare lo racchiude forzatamente tra apici singoli.

Quindi sembra che dovrai filtrare posts_where dopo tutto. Puoi provare a rimuovere gli apici da quella specifica stringa invece di generare manualmente la condizione.

22 set 2010 23:31:57
Commenti

questo utilizzo è pensato solo per ordinare i dati... ma ho provato e non funziona. Quando ho visto la tua risposta ho pensato wow questa è la soluzione....

User User
22 set 2010 23:37:29
6

Consiglio di analizzare il tuo array $args e convertirlo in una stringa prima di passarlo a query_posts. Quando crei l'array $args, il sistema convertirà automaticamente il numero 5 nella stringa "5" quando l'array viene riconvertito in stringa.

Quindi usa invece questo:

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

In questo modo stai passando le stesse informazioni a query_posts, ma dovrebbe passare il numero 5 anziché la stringa "5".


Aggiornamento

Dato che ora abbiamo scoperto che meta_value memorizza stringhe anziché numeri, e non puoi effettivamente fare un confronto maggiore/minore con le stringhe. Tuttavia, dopo alcune ricerche aggiuntive mi sono imbattuto nel flag di query meta_value_num.

Se esegui la seguente chiamata query_posts:

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

Dovresti ottenere il comportamento desiderato. meta_value_num dice a WordPress di valutare i tuoi meta_value come numeri anziché come stringhe.

22 set 2010 23:29:24
Commenti

Ho provato e produce esattamente lo stesso risultato. In effetti ho persino seguito il percorso da funzione a funzione nel WordPress-Core e la stringa viene suddivisa su & e trasformata in un array prima di essere elaborata....

User User
22 set 2010 23:33:55

Secondo il Codex: Nota che il valore 99 sarà considerato maggiore di 100 poiché i dati sono memorizzati come stringhe, non come numeri. Quindi meta_value viene memorizzato come stringa... ecco perché WordPress aggiunge gli apici. La mia prossima domanda sarebbe: puoi descrivere come "non funziona"? Restituisce comunque dei dati?

EAMann EAMann
22 set 2010 23:47:45

Sì, hai ragione! Come ho detto sopra, non importa cosa faccia viene racchiuso in '5'. MySQL non può confrontare qualcosa a livello numerico se è racchiuso tra '', quindi mi chiedo perché WordPress abbia implementato questa funzione se non funziona. No, restituisce risultati ma semplicemente non quelli desiderati.

User User
22 set 2010 23:50:38

Vedi il mio aggiornamento sopra. Aggiungere orderby=meta_value_num dovrebbe risolvere il problema se stai utilizzando WP 2.8.4 o versioni successive.

EAMann EAMann
23 set 2010 00:12:55

Grazie per tutti gli sforzi. Ma anche questo non funziona. Ho approfondito molto questo argomento e semplicemente non è supportato da WP. Creerò un ticket per questo problema perché è davvero facile da risolvere e renderebbe possibili così tante cose!

User User
23 set 2010 21:31:34

@Joakim Sì, questa funzionalità è supportata da WP. Leggi il ticket che ho citato sopra dove è stata aggiunta la funzionalità. Forse puoi fornirci un esempio di codice più ampio di ciò che stai cercando di fare... potrebbe esserci un problema diverso.

EAMann EAMann
23 set 2010 22:05:47
Mostra i restanti 1 commenti
0

WordPress tratta tutti i 'valori' come stringhe e aggiunge apici singoli attorno ad essi nella query finale, quindi anche SQL è costretto a trattarli come stringhe e non come numeri. Puoi rimuovere questi apici con un filtro:

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

E assicurati di avere 'type' => 'NUMERIC' o simile

7 feb 2025 18:42:35