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 know how to write querry args for WP_Query if it's a single key : for example, if query posts with the metakey of 'type'--

$query_args['type'] = (array)$type;

Now, the problem is-- the item I want to querry is saved inside an array, this array is saved as a postmeta. This is my array:

$details = array(
'user_id' => 0,
'type'   => '',
'amount' => 0,
);

I saved this array in wordpress postmeta:

update_post_meta($post_id, 'details', $details );

Now I want to query for posts that have the same metakey of 'type'. How?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

Jenny, first of all, I think you may be better off using Taxonomy Parameters in you queries. However, there are a couple of hackish ways to do what you want to some extent.

$my_query = new WP_Query( 'post_type=post&posts_per_page=-1' );

$posts = $my_query->get_posts();
foreach ( $posts as &$post ) {
    // Get the details and unset if thy type is unwanted
    $details = get_post_meta( $post->ID, 'details', true );
    if ( isset($details['type'])
        and $details['type'] != 'my_type ')
            unset( $post );
}

This will filter out posts that don't match a type of my_type in your details meta for the post.

However, note the performance issue - get_post_meta is called for each and every post, resulting in queries to the database. Ouch!

There is a more complex way to do this using a custom query to get all the meta at once like so:

$sql = "SELECT `post_id`, `meta_value`".
    " FROM {$wpdb->postmeta}".
    " WHERE `meta_key` = 'details'";

// Gather my meta
$metas = $wpdb->get_results( $sql );
$details = array();
foreach  ( $metas as $meta ) $details[$meta->post_id] = unserialize($meta->meta_value);

$my_query = new WP_Query( 'post_type=post&posts_per_page=-1' );
$posts = $my_query->get_posts();

foreach ( $posts as &$post ) {
    // Filter the unwanted posts
    if ( isset($details[$post->ID]['type'])
        and $details[$post->ID]['type'] != 'my_type' )
            unset( $post );
}

This way you did only one extra query, by bringing the meta in in the beginning. A couple of things to note here:

  • the basic principal is there - get all the posts, and filter them by unsetting
  • $wpdb` should be in scope (if you're inside a function or method bring it in as a global)
  • if you're going to play around with " WHERE meta_key = 'details'"; make sure you escape what you feed into the query, otherwise it will be at risk of SQL injection
  • wrap these into functions that will allow you to reuse them
  • if you have a lot of posts in the query, this can get slow
share|improve this answer
    
Thanks for the idea of taxonomy, I think that could be the best way to handle my additional querry terms. –  Jenny Oct 19 '11 at 7:47

This is not possible, you have to save each element of your array as separate meta fields. As far as MySQL is concerned, your field is just a string of text, it doesn't have the ability to parse a PHP array.

share|improve this answer
    
Exactly. If you ever need to run a query on a field in that array, you'll need to split it out into its own meta value. Otherwise, the array is serialized, and you can't use WP_Query to run a search. –  EAMann Oct 19 '11 at 4:54

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.