How to filter or sort a WP_Query by one or more custom fields
If you’re familiar with WP_Query, you’ve probably used the meta_query
parameter to filter results by one or more custom field values.
But did you know that you can also use meta_query
to sort the results, if you give the meta_query
segment a named key
? This feature was introduced in WordPress 4.2.
Below are examples of both applications. If you have trouble writing your custom meta queries, this WP_Meta_Query generator could be useful.
Filter a query by a custom field
The following example uses the meta_query
parameter to filter the query results by one or more custom field values:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
$args = [ 'post_type' => 'cars', 'post_status' => 'publish', 'meta_query' => [ [ 'key' => 'is_featured', 'compare' => 'EXISTS' ] ] ]; // Run the query $query = new WP_Query( $args );
Order a query by a custom field
The following example uses the meta_query
parameter to order the query results by one or more custom field values. In this snippet, we are using featured
as the meta_query
segment name. It can then be use within the orderby
clause:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
$args = [ 'post_type' => 'cars', 'post_status' => 'publish', 'meta_query' => [ 'featured' => [ 'key' => 'is_featured', 'compare' => 'EXISTS' ] ], 'orderby' => [ 'featured' => 'DESC' ] ]; // Run the query $query = new WP_Query( $args );
Order a query by multiple custom fields
To sort by multiple custom fields, you have to use multiple meta_query
keys. In the following example, we first sort by featured
, then by rating
:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
$args = [ 'post_type' => 'cars', 'post_status' => 'publish', 'meta_query' => [ 'featured' => [ 'key' => 'is_featured', 'compare' => 'EXISTS' ], 'rating' => [ 'key' => 'avg_rating', 'compare' => 'EXISTS', 'type' => 'numeric' ] ], 'orderby' => [ 'featured' => 'DESC', 'rating' => 'DESC' ] ]; // Run the query $query = new WP_Query( $args );
Order a query by multiple custom fields that can be empty for some posts
If you want to order a query by a custom field, and that field does not exist for some posts, these posts will disappear. To prevent this, you can set up the arguments as follows, without named segments (like in the previous example).
The following query first sorts by the custom field, then by post title. Posts without the custom field will be sorted by post title and added after the ones with the custom field:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
<?php $args = [ 'post_type' => 'cars', 'post_status' => 'publish', 'meta_query' => [ 'relation' => 'OR', [ 'key' => 'my_custom_field', 'compare' => 'NOT EXISTS' ], [ 'key' => 'my_custom_field', 'compare' => 'EXISTS' ] ], 'orderby' => [ 'meta_value_num' => 'DESC', // Sort by 'my_custom_field' first. Use DESC to show posts with the field existing first. Use ASC to show posts with the field existing last. Use 'meta_value' instead if the custom field does not contain numeric values. 'title' => 'ASC' // Sort by post title A-Z ], 'meta_key' => 'my_custom_field', ]; // Run the query $query = new WP_Query( $args );
Make sure to use meta_value
in line 16 if the custom field does not contain numeric values.
It’s important that the NOT EXISTS
comparison is before the EXISTS
comparison. See this StackExchange question for more info and examples.
Also be aware that ordering with named meta_query keys does not work in this setup.