I'm trying to query for a custom post type for a gallery system. I have a checkbox to set a gallery as a "featured" gallery (set up through More Fields plugin) - if this is checked then the meta value becomes 1 and then if unchecked it becomes 0. All good. However if the box has never been checked then the meta key is never created, meaning I can't query for NOT LIKE 1 because it doesn't exist.

The query I want is to pull out 4 galleries that aren't marked as '1' in this meta value, but also those that don't have this value at all. Is there a way to always give newly added posts a default value for this meta key (ie always make them 0 by default if the box is left unchecked) or is there a way to query for the key not yet being set?

My current query is:

$args = array(
                        'post_type' => 'gallery',
                        'showposts' => 4,
                        'meta_key' => 'gal-ID',
                        'order_by' => 'meta_value',
                        'order' => 'ASC',
                        'meta_query' => array( array(
                                            'key' => 'main-gal',
                                            'value' => false,
                                        ) ),
                        ) );

And I've tried various attempts with 'compare' => 'NOT LIKE', '!=' etc etc.

Any ideas? This ticket seems to imply it's something that ought to be sorted out:



4 Answers 4


That massive function was a bit scary, I got this working like so - with two arguments (that exclude the features)

$args = array(

    'meta_query' => array(
        'relation' => 'OR',
            array( // new and edited posts
                'key' => 'Set as Featured Post',
                'compare' => '!=',
                'value' => 1

            array( // get old posts w/out custom field
                'key' => 'Set as Featured Post',
                'value' => '1',
                'compare' => 'NOT EXISTS'
    'posts_per_page' => 30

  • My first array is overriding my second with this solution. It seems maybe you can't double query the same field? Apr 2, 2013 at 19:51

As per Custom Field Parameters in Codex, special NOT EXISTS compare is available since WP version 3.5

Technically it produces something like following SQL query in posts requests:

$posts = get_posts( array(
    'meta_query' => array(
            'key'     => 'wrong',
            'compare' => 'NOT EXISTS',
) );
SELECT *,wp_posts.ID
FROM wp_posts
LEFT JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'wrong')
WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') AND (wp_postmeta.post_id IS NULL)
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 5

It works by joining meta table on provided key and only selecting records where that hadn't resulted in meaningful data (IS NULL). So it works only for case when key doesn't exist at all and won't work for keys that exist with falsy values.

  • I'm intrigued by this NOT EXISTS compare. As a work around for unset meta keys, I just save a 0 on the save_post hook if the meta key isn't set. How does NOT EXISTS work? Will it sort the OP's query by main-gal and then fill in the 4 with the posts that don't have that meta? Jan 10, 2013 at 13:35
  • @helgatheviking I've elaborated on mechanics in answer
    – Rarst
    Jan 10, 2013 at 21:46

As the ticket pointed out, it's not supported.. until then you'll have to rely on a custom solution.

A few users have asked for this before, or at least asked how to do it over on the WordPress.org forums, so i wrote a function to do the job which i never kept hold of(pastebinned), fortunately i found the original topic where i provided the pastebin link(which shouldn't expire).


I wrote that 8 months ago and i've not tested it(since then), so let me know of any issues.

Hope that helps..

  • Cool, thanks for this - will test it out later this evening and let you know what happens.
    – artparks
    Jul 27, 2011 at 11:55

The simplest method, albeit not the cleanest:

$args = array(
    'post_type' => 'gallery',
    'posts_per_page' => -1,
    'meta_key' => 'gal-ID',
    'order_by' => 'meta_value',
    'order' => 'ASC',
    'meta_key' => 'main-gal',
    ) );

This will give you all your galleries sorted by the meta key. The next step is to figure out if the galleries with the value 1 come after or before the other posts. This way you can either:

  • Process items until you've processed either 4 gallery items, or reached a post with a meta value of 1
  • Skip over the posts with a meta value 1 then start processing when you reach the first non-1 value

Other methods not requiring a custom SQL statement:

  • Doing a query to find the galleries you dont want, using it to fill an array of post IDs, then doing a second query, passing that array in as posts to exclude
  • Using a taxonomy instead of custom fields ( solves this quite nicely and puts a lot of other nice improvements in free of charge so its saving you time too )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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