0

In wp_postmeta I have a meta_key which stores colon separated strings such as "CA:Georgia:NY".

So for meta_key='state' there can be several entries like:

For post 1 = "CA:Georgia:NY'

For post 2 = "CA"

For post 3 = "Georgia:CT'

For post 4 = "WA:CA"

I want to make a query to find out all the posts for which the meta_key contains 'CA' or 'Georgia'.

I building the WP_Query arguments dynamically.

$statelist = array();
$args = array(
    'post_type'     => 'post',
    'meta_query'    => array(
    'relation'      => 'OR')
);

if($_GET['state'] != NULL)
{
    $state_arr = explode( ',', $_GET['state']);
    for($i=0; $i<count($state_arr); $i++)
    {
        //tried also with relation = OR for first entry
        $current_arr = array('relation' => 'OR' , 
        array(
            'key' => 'state',
            'value' => $state_arr[$i],
            'compare' => 'LIKE'
        ));
        array_push($statelist, $current_arr);
    }
}

if(count($statelist) >= 1)
    array_push($args['meta_query'], $statelist);

But I'm always getting the Query as follows:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id)
WHERE 1=1
  AND ((((wp_postmeta.meta_key = 'state'
          AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%Georgia%')) **
        AND** ((mt1.meta_key = 'state'
                AND CAST(mt1.meta_value AS CHAR) LIKE '%CA%'))))
  AND wp_posts.post_type = 'post'
  AND (wp_posts.post_status = 'publish'
       OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC LIMIT 0,
                                       50

As a result this query is picking up only post 1 = "CA:Georgia:NY'

Though I want all the posts where meta_key='state' has either 'CA' or 'Georgia'. Despite explicitly creating the array with relation OR it is switching to default AND.

What should be the ideal way to construct the Query arguments? It would be great if experts throw some light.

0
2

Your argument structure is not correct. It should be like

[meta_query] => Array
    (
        [0] => Array
            (
                [key] => state
                [value] => a
                [compare] => LIKE
            )

        [1] => Array
            (
                [key] => state
                [value] => b
                [compare] => LIKE
            )

        [2] => Array
            (
                [key] => state
                [value] => c
                [compare] => LIKE
            )

        [relation] => OR
    )

But it is like

[meta_query] => Array
        (
            [relation] => OR
            [0] => Array
                (
                    [0] => Array
                        (
                            [relation] => OR
                            [0] => Array
                                (
                                    [key] => state
                                    [value] => a
                                    [compare] => LIKE
                                )

                        )

                    [1] => Array
                        (
                            [relation] => OR
                            [0] => Array
                                (
                                    [key] => state
                                    [value] => b
                                    [compare] => LIKE
                                )

                        )

                    [2] => Array
                        (
                            [relation] => OR
                            [0] => Array
                                (
                                    [key] => state
                                    [value] => c
                                    [compare] => LIKE
                                )

                        )

                )

        )

Change your code in this way to match recommended structure

$statelist = array();
$args = array(
    'post_type'     => 'post',
    'meta_query'    => array(
    'relation'      => 'OR')
);

if($_GET['state'] != NULL)
{
    $state_arr = explode( ',', $_GET['state']);
    for($i=0; $i<count($state_arr); $i++)
    {
        //tried also with relation = OR for first entry
        $current_arr = array(
            'key' => 'state',
            'value' => $state_arr[$i],
            'compare' => 'LIKE'
        );
        array_push($statelist, $current_arr);
    }
}

if(count($statelist) >= 1) {
    $statelist['relation'] = 'OR';
    $args['meta_query'] = $statelist;
}

Ref: https://codex.wordpress.org/Class_Reference/WP_Meta_Query

1
  • Fantastic!!! Thank you Sumit! Worked like a charm... – raich Feb 2 '16 at 18:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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