Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am using query_posts( $args ) to filter the Loop. I want to filter posts based on their meta_value "vote", sometimes smaller than, sometimes equals and so on....

I definitly want to use the query_posts() function and pass my filter through $args! I don't want to use add_filter('posts_where', 'filter_where'); and then add an AND statement to the query.

I want to use the given functionality of WordPress to filter posts with meta_key, meta_value and meta_compare like this:

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

query_posts( $args );

The result of this is:

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

The problem of that is:

wp_postmeta.meta_value >= '5' 

It should be:

wp_postmeta.meta_value >= 5

Then it would work fine.

I don't understand why WordPress adds quotes.

I'm using the predefined parameter from WordPress (<, >, <=, >=) and it's obvious that this will only work with numbers and not strings which would need to be in quotes.

The documentation says:

Returns posts with custom field key of 'miles' with a custom field value that is LESS THAN OR EQUAL TO 22

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

share|improve this question
add comment

3 Answers

Since WP 3.1, you can cast the meta value to anything you want using the 'type' argument in 'meta_query':

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

query_posts( $args );
share|improve this answer
    
This is a great answer - totally does the trick. –  Samuel Hulick Oct 23 '11 at 11:24
    
''type' => 'numeric',' solved my problem But i doubt that it shouldn't contain comma –  vaibhav Jan 2 '13 at 17:36
add comment

From quick look over documentation meta_value seems to be purposed for strings and for numerical values there is meta_value_num.

See Orderby Parameters

Update

Did some digging.

meta_value_num is indeed ignored for the purpose of filtering. I think they simply forgot to add that part. :)

The issue is that WP_Query correctly receives number as int (passing as array doesn't matter), but it passes generated meta_compare condition through $wpdb->prepare() and explicitly marks value as %s string. In which case prepare forcefully single-quotes it.

So it seems you'll have to filter posts_where after all. You can try to just unquote that specific string instead of generating condition manually.

share|improve this answer
    
this usage its only ment for sorting data... but i tried it and it doesn't work. When i saw your answer i though man thats the solution.... –  Joakim Sep 22 '10 at 20:37
add comment

I would recommend parsing your $args array and converting it to a string before passing it into query_posts. When you create the $args array, the system will automatically convert the number 5 into a string "5" when the array is turned back into a string.

So use this instead:

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

That's still passing the same information into query_posts, but should pass in the number 5 rather than a string "5".


Update

Since we've now discovered that meta_value stores strings rather than numbers, and you can't effectively do a greater than/less than comparison with strings. However, after some more research I stumbled upon the query flag meta_value_num.

If you run the following query_posts call:

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

Then you should get be behavior you want. meta_value_num tells WordPress to evaluate your meta_values as numbers rather than strings.

share|improve this answer
    
I tried that it produces exactly the same. In fact i even followed the way from function to function in WordPress-Core and the string gets exploded at & and turned into an array before it gets proccessed.... –  Joakim Sep 22 '10 at 20:33
    
According to the Codex: Note the value 99 will be considered greater than 100 as the data is stored as strings, not numbers. So meta_value is being stored as a string ... which is why WordPress adds the quotes. My next question would be, can you describe how this is "not working?" Is it returning data at all? –  EAMann Sep 22 '10 at 20:47
    
Yes, you are right! Like i said above no mather what i do i gets wrappet into '5'. Mysql can't compare something on anumerical level if its wrapped into '' so i'm wondering why wordpress has implemented this function if it doesnt work. No it returns result but just not the desired ones. –  Joakim Sep 22 '10 at 20:50
    
See my update above. Adding orderby=meta_value_num should fix the problem if you're running WP 2.8.4 or later. –  EAMann Sep 22 '10 at 21:12
    
Thanks for all the efforts. But that does although not work. I really digged into this topic and it's just not supported by WP. I will put create a ticket for this issue because it really easy to fix and makes so many things possible! –  Joakim Sep 23 '10 at 18:31
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.