WordPress Meta_Query: Everything You Need to Know

One of the most powerful tools in WordPress is the ability to add custom fields to posts. Many developers use Advanced Custom Fields or custom meta fields for posts. You can use the built in WordPress meta query function to query custom fields on a WordPress site.

In this post we’ll be going over how to query posts by custom field using the meta_query function in WordPress. This is helpful for sites with a lot of custom functionality. Keep in mind you’ll want to be familiar with PHP.


Query Posts By a Meta Value

Probably the most popular way to query posts with a custom field is targeting one specific meta value.

For example let’s say we have a site where posts have a custom field used to determine if a post is “featured”. This is common when making a featured section on a WordPress site.

<?php
$meta_query_args = array(
'meta_query' => array(
array(
'key' => 'featured_post',
'value' => 'yes',
'compare' => '='
)
)
);
$meta_query = new WP_Query( $meta_query_args );

Of course the above code will vary depending on what you title your fields and postmeta keys but the ‘key’ in the meta_query parameter is the name of the custom field. While the ‘value’ is the matching value we are querying posts for. The ‘compare’ field is used for a range of comparison operations we’ll go over later in the post.

Using this in WP_Query will allow us to get an array that is great for loop functions to display posts. In this post we’ll only be going over the meta_query functions rather than how to display WP_Query output.


Query Posts By Multiple Meta Values

If you want to check a meta key value against multiple values it’s best to use the ‘IN’ operator. This is done by using an array for ‘value’ in your meta query.

<?php
$meta_query_args = array(
'meta_query' => array(
array(
'key' => 'city_name',
'value' => array('New York City', 'London', 'San Francisco'),
'compare' => 'IN'
)
)
);
$meta_query = new WP_Query( $meta_query_args );

Query Posts By Multiple Meta Keys

Now that we’ve queried posts with a single meta key let’s do one with multiple fields/keys being queried. This will allow you to query posts based on multiple custom fields. This example combines both things we did above by nesting the queries into an array and adding a ‘relation’ to the meta_query.

<?php
$meta_query_args = array(
'meta_query' => array(
'relation' => 'AND',
array(
array(
'key' => 'city_name',
'value' => array('New York City', 'London', 'San Francisco'),
'compare' => 'IN'
),
array(
'key' => 'featured_post',
'value' => true,
'compare' => '='
)
)
)
);
$meta_query = new WP_Query( $meta_query_args );

The ‘relation’ field can be set to ‘AND’ or ‘OR’ so you can require all conditions to be met or just one.


Query Posts Between Dates

Another popular query when getting WordPress posts using meta_query is to query dates. Here’s how to only query posts between two dates.

This function assumes your date is formatted as YYYY-MM-DD in structure. If you’re using Advanced Custom Fields you’ll want to ensure your return date format is set to return in this format.

<?php
$meta_query_args = array(
'meta_query' => array(
array(
'key' => 'my_date_field',
'value' => array( '2022-01-01', '2022-12-31' ),
'type' => 'date',
'compare' => 'BETWEEN'
)
)
);
$meta_query = new WP_Query( $meta_query_args );

If you’re using a Unix timestamp it’s even easier to query posts between dates. This code snippet will convert dates to Unix timestamps and compare between them.

<?php
$meta_query_args = array(
'meta_query' => array(
array(
'key' => 'my_date_field',
'value' => array( strtotime('2022-01-01'), strtotime('2022-12-31') ),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
)
);
$meta_query = new WP_Query( $meta_query_args );

Of course you can also use the greater than or less than operator in the above queries to find posts before/after a date.


Meta Query Comparison Operators

There are a few operators that will be helpful in querying your posts by meta query. Here is a quick breakdown of each comparison operator and how you can use them.

  • ‘=’ Queries meta keys that equal a meta value
  • ‘!=’ Queries meta keys that are NOT equal to a meta value
  • ‘>’ Queries meta keys that are greater than the meta value
  • ‘>=’ Queries meta keys that are greater than & equal to the meta value
  • ‘<‘ Queries meta keys that are less than the meta value
  • ‘<=’ Queries meta keys that are less than & equal to the meta value
  • ‘LIKE’ Queries meta keys that contain a word/phrase (for example querying “red” would match the phrases “Red”, “looksred”, and “redstyle”)
  • ‘NOT LIKE’ The opposite of above
  • ‘IN’ Queries meta keys where the value exists in an array
  • ‘NOT IN’ Queries meta keys where the value exists not in an array
  • ‘BETWEEN’ Queries meta keys where the value is between two numbers
  • ‘NOT BETWEEN’ Queries meta keys where the value is not between two numbers
  • ‘EXISTS’ Queries meta keys where the value exists at all
  • ‘NOT EXISTS’ Queries meta keys where the value doesn’t exist at all
  • ‘REGEXP’ Queries meta keys based on a regular expression
  • ‘NOT REGEXP’ Opposite of above REGEXP

Keep in mind if you aren’t feeding an array to meta_query you’ll need to use meta_compare in your WP_Query args.


How To Sort Posts By Meta Fields

Of course WordPress lets you sort posts using your custom fields using the ‘orderby’ option in WP_Query. This is easy using the orderby parameter in your WP_Query args.

You’ll need to set ‘orderby’ to be ‘meta_value’ and then set a ‘meta_key’ value to your field name. By default this is most useful when want your query to return alphabetically or sorted by number when your your field is a number.

Of course you can also set the ‘post_type’ parameter of your WP_Query to ‘post’, ‘page’, or a custom post type value.

<?php
$meta_query_args = array(
'post_type' => 'page',
'order' => 'ASC',
'meta_key' => 'city_name',
'orderby' => 'meta_value'
);
$meta_query = new WP_Query( $meta_query_args );

If your meta_key field is a number you’ll want to use the ‘meta_value_num’ value for orderby to indicate to WordPress that it’s an integer.


Congratulations you’ve just leveled up as a WordPress developer.

Learning meta query is an incredibly powerful tool when building custom functionality in WordPress. WordPress turns the parameters in your meta_query into SQL and queries your database. If you are building any custom functionality it’s recommended to use built-in WordPress functions rather than hard coding MySQL queries.

If you want to deeper your WordPress knowledge I recommend checking out the documentation for WP_Query.

Picture of Andy Feliciotti

Andy Feliciotti

Andy has been a full time WordPress developer for over 10 years. Through his years of experience has built 100s of sites and learned plenty of tricks along the way. Found this article helpful? Buy Me A Coffee

4 Responses

  1. Hi, is it possible to have multiple meta_queries with AND / OR?

    So I have four variables stored in custom fields, ‘user-1’, ‘user-2’ (both to be checked against current user), ‘date’ (checked against current date), ‘status’. (action/filing) and what i want to achieve in the returned posts is the following;

    Result should be as follows;

    Query 1 is == ‘user-1’ OR ‘user-2’ can be current user

    Query 2 is == AND ‘date’ is earlier than today AND ‘status’ is (action)

    I can get it to work using just one ‘user’ custom field, because then it is just three AND relations, but not to have both queried as it then feels like i have to have two meta_queries, which I don’t know is possible? I have been using Oxygen repeater with query builder to make my query rather than coding it directly. Any thoughts on the matter would be appreciated.

Leave a Reply

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

WordPress Tips Monthly
Get the latest from SmartWP to your inbox.