Ultimate Guide to meta_query – Get and Order Posts by Meta Values
Table of Contents
In this post I assume that you already have basic knowledge how to work with WP_Query class in WordPress. Before I begin, I want to show you some very simple examples. The similar examples you can find in WordPress Codex.
As you know all the posts have the metadata you can populate in “Custom fields” metabox (the metabox by the way can be hidden). So, for example, if you want to get a post with meta key show_on_homepage
and meta value on
, you can do it the following way:
$rd_args = array( 'meta_key' => 'show_on_homepage', 'meta_value' => 'on' ); $rd_query = new WP_Query( $rd_args );
Otherwise, if you need to query all posts except the ones with this pair of meta key and value, you can use the following parameters:
$rd_args = array( 'meta_key' => 'show_on_homepage', 'meta_value' => 'on', 'meta_compare' => '!=' ); $rd_query = new WP_Query( $rd_args );
Do not forget that all examples in this post are simplified, so, some of WP_Query parameters are missing, e.g posts_per_page
or post_type
.
If you are interested in other meta_compare
parameter values, please look at “compare” parameter description below, because both of them accept the same values.
This was very very simple examples, just an introdution. But this post is about meta_query
parameter. This parameter allows us to create a really cool post filters and search scripts.
Query Posts by a Meta Value
The simple example below allows you to get all the posts with a specific custom field value. Let’s just get all the posts with custom field name “color” and custom field value white
.
// the meta_key 'color' with the meta_value 'white' $rd_args = array( 'meta_query' => array( array( 'key' => 'color', 'value' => 'white' ) ) ); $rd_query = new WP_Query( $rd_args );
If you look at the post edit page (in admin area) in any post which matches the query, you will see the following in the “Custom Fields” section:
Let’s do the opposite thing – get all the posts except the ones with meta key “color” and meta value white
:
$rd_args = array( 'meta_query' => array( array( 'key' => 'color', 'value' => 'white', 'compare' => '!=' ) ) ); $rd_query = new WP_Query( $rd_args );
Get Posts by Multiple Meta Values
Now let’s get all the posts with white
OR green
“color” custom field value:
// custom field name is color and custom field value is 'white' OR 'green' $rd_args = array( 'meta_query' => array( array( 'key' => 'color', 'value' => array('white','green'), 'compare' => 'IN' ) ) ); $rd_query = new WP_Query( $rd_args );
Get all the posts (products in online shop for example) except white products and green products:
$rd_args = array( 'meta_query' => array( array( 'key' => 'color', 'value' => array('white','green'), 'compare' => 'NOT IN' ) ) ); $rd_query = new WP_Query( $rd_args );
How to use “compare” in meta_query
As you can see in example below and in further examples too, there is a compare
parameter in every of them. Now I would like to show which values it can accept and what do they mean.
=
(or not set) Equal to,!=
– Not equal to,<
– Less than,<=
– Less or equal to,>
– Greater than,>=
– Greater than or equal to, example:
// the product price in this example is 2000 or more than 2000: $args = array( 'meta_query' => array( array( 'key' => 'price', 'value' => 2000, 'type' => 'numeric', // specify it for numeric values 'compare' => '>=' ) ) );
LIKE
– Allows to search in meta values for a specific string, in the example below the query returns all the posts where “first_name” name containsJohn
, it can be alsoJohnny
,Johnathan
,somethingJohnsomething
:
$args = array( 'meta_query' => array( array( 'key' => 'first_name', 'value' => 'John', 'compare' => 'LIKE' ) ) );
- Two more things: first – it is not case sensitive, second – wildcard symbols
@
are not necessary. NOT LIKE
– similar toLIKE
just works in an opposite way – meta value mustn’t contain the given string.IN
– posts meta value must contain one of the values of the given arrayNOT IN
– meta values must not contain ANY of the values in the given array.BETWEEN
– post meta value should be between the given range of values, example:
// the product price is more than 2000 and less than 4000 $args = array( 'meta_query' => array( array( 'key' => 'price', 'value' => array( 2000, 4000 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ) ) );
- It can also work for dates
NOT BETWEEN
– not in a given range.EXISTS
(WordPress >= 3.5) – If meta value of a specific meta key exists or empty / null.
$args = array( 'meta_query' => array( array( 'key' => 'misha_key', 'compare' => 'EXISTS' ) ) );
- So, actually it checks if a meta key exists, you do not even have to pass any value with this parameter.
NOT EXISTS
(WordPress >= 3.5) – if a given meta key doesn’t exist at allREGEXP
(WordPress >= 3.7) – it allows you to compare meta values with regular expression, example:
$args = array( 'meta_query' => array( array( 'key' => 'misha_key', 'value' => '^[0-9]*$', // "misha_key" must be only numbers 'compare' => 'REGEXP' ) ) );
NOT REGEXP
(WordPress >= 3.7) – Similar toREGEXP
but meta values must not match your given regular expressionRLIKE
(WordPress >= 3.7) – it is the synonym toREGEXP