Wordpress - Using OR conditions in meta_query for query_posts argument

Use 'relation' => 'OR' as in the Codex example below:

$args = array(
    'post_type' => 'product',
    'meta_query' => array(
        'relation' => 'OR', /* <-- here */
        array(
            'key' => 'color',
            'value' => 'blue',
            'compare' => 'NOT LIKE'
        ),
        array(
            'key' => 'price',
            'value' => array( 20, 100 ),
            'type' => 'numeric',
            'compare' => 'BETWEEN'
        )
    )
);
$query = new WP_Query( $args );

That will give you an OR across all of your meta_query blocks. If what you need is something like WHERE "instructor" = 1128 AND (class_1_days = "value1" OR class_1_days = "value2") then something like this would do it if your data wasn't serialized.

$args = array(
        'taxonomy' => 'courses', 
        'term' => 'drawing', 
        'post_type' => 'school', 
        'paged' => $paged,
        'meta_query' =>
            array(
                array(
                    'key' => 'instructor',
                    'value' => '1128',
                    'compare' => 'LIKE',
                ),
                array(
                    'key' => 'class_1_days',
                    'value' => array('Friday','Saturday')
                    'compare' => 'IN',
                )
            )

    );

Given that you have serialized data this is going to be difficult. You could write a filter for posts_where but I'd expect the result to inefficient and prone to error.

The correct approach for cases like this where you need to search/filter/sort by some piece of information is, in my experience, to not store your data as a serialized array in the first place. That is simply the wrong approach if you need queries like this.

If I were taking over this project I would loop through the data that needs to be queried in this way and re-save each piece at a key/value pair. The parts you are not querying can stay serialized. There is no (good) way to do this in MySQL with MySQL functions either as part of the query you are attempting or as some stand-alone query. I have seen attempts at creating a MySQL "unserialize" function but I don't see the point. Re-saving the data is the way to go.

It should be a fairly simple query to get all of the class_1_days data. Then loop over it and save the parts you need to query as independent keys and put the rest back as serialized data.


According to the WordPress codex nested arrays can be used to construct complex queries. In your example your need something like this:

$args = array(
    'taxonomy' => 'courses', 
    'term' => 'drawing', 
    'post_type' => 'school', 
    'paged' => $paged,
    'meta_query' =>
        array(
           'relation' => 'AND', // default relation
            array(
                'key' => 'instructor',
                'value' => '1128',
                'compare' => 'LIKE',
            ),
            array(
                'relation' => 'OR',
                array(
                    'key' => 'class_1_days',
                    'value' => 'Friday',
                    'compare' => 'LIKE',
                ),
                array(
                    'key' => 'class_1_days',
                    'value' => 'Saturday',
                    'compare' => 'LIKE',
                ),
            )
        )
);