meta_query with relation = AND not working as expected when combining EQUALS with NOT EQUALS

I want to query my player post type for all those who do not have certain colortoken meta values (note that a player can have multiple colortoken meta_keys). I assumed I could do this:

$args = array(
‘post_type’ => ‘player’,
‘post_status’ => ‘any’,
‘posts_per_page’ => 1,

‘meta_query’ => array(
‘relation’ => ‘AND’,
array(
‘key’ => ‘playerlevel’,
‘value’ => 12,
),
array(
‘key’ => ‘colortoken’,
‘value’ => ‘blue’,
‘compare’ => ‘!=’,
),
),
);

$playersQuery = get_posts($args);

This should return all players who are level 12 but don’t have a blue colortoken. This works… but only if a player has a single colortoken. If I have a player post with two colortoken meta_values:

Post ID => 158
playerlevel => 12
colortoken => red
colortoken => blue

…then this player (ID 158) will be returned within the array, despite the fact that I asked for colortoken != blue. This seems to be an issue when there are multiple meta values with the same key, but the one you’re trying to negate isn’t the first one (so, if blue was the first value rather than the second, or it was the only colortoken meta value, then post 158 wouldn’t be returned).

This only seems to be a problem when I combine relation => AND with a compare => ‘=’ & compare => ‘!=’. If both of the compares are = (or removed, since it’s implicit), then the returned array is as expected, even with multiple duplicate meta key/value pairs.

Am I missing something, or is this some kind of expected behaviour?

Read more here:: meta_query with relation = AND not working as expected when combining EQUALS with NOT EQUALS

Leave a Reply

Your email address will not be published. Required fields are marked *