2

I'm looking for a way to basically have an OR relationship between the date_query and the meta_query. Basically I want to combine the two WP_Query's.

Get the posts from the last two weeks

$args = array(
    'post_type'  => 'post',
    'orderby'    => 'date',
    'posts_per_page' => -1,
    'date_query' => array(
        array(
            'after' => '2 weeks ago'
        )
    )
);

Get posts with certain meta_value, such as sticky = 'true'

$args = array(
    'post_type'  => 'post',
    'orderby'    => 'date',
    'posts_per_page' => -1,
    'meta_query' => array(
        array(
            'key'     => 'sticky',
            'value'   => true,
            'type'    => 'BOOLEAN',
        ),
    ),
);

How can I combine these two queries into one--but so that if a post meets either the date OR the meta_query requirement, it is selected.

  • 1
    You will probably have to make 2 separate queries (one for date and other for meta) and merge them. Read more from this question's top answer. Im not 100% sure, maybe there's a better way, someone else might know it better. Alternative way would be to write your own SQL or use Combined Query plugin. – N00b Jan 19 '16 at 2:18
2

It might be possible to achieve this by using the post clauses filters and rewriting the generated SQL query.

You can also run 3 queries,

  • One very lean query to get the desired posts from the date_query

  • One very lean query to get all the posts from the meta_query

  • One final query to get the complete query object. This help specially with pagination if you ever want to paginate the query. This also sorts the posts correctly in order.

You can try the following

$defaults = [
    'post_type'      => 'post',
    'orderby'        => 'date',
    'posts_per_page' => -1,
    'fields'         => 'ids' // Only return post ID's for performance
];

// Query 1
$date_query = [
    [
        'after' => '2 weeks ago'
    ]
];
$query1 = new WP_Query( array_merge( $date_query, $defaults ) );

// Query 2
$meta_query = [
    [
        'key'     => 'sticky',
        'value'   => true,
        'type'    => 'BOOLEAN',
    ]
];
$query2 = new WP_Query( array_merge( $meta_query, $defaults ) );

// Final query
// Get all the post ID's from the two queries and merge into one array
$ids = array_merge( $query1->posts, $query2->posts )
// Make sure we have an array of id's before continueing to avoid unexpected results
if ( $ids ) {
    // Remove possible duplicates
    $ids = array_unique( $ids );
    // Set fields back to all to get full post objects
    $defaults['fields']    = 'all';
    // Add extra parametes
    $defaults['post__in']    = $ids; // Set the array of ids to post__in
    // $defaults['order']    = 'ASC'; // If you want to keep the post order according to post__in
    //$defaults['orderby'] = 'post_in'; // If you want to keep the post order in post__in

    // Run our query
    $q = new WP_Query( $defaults );
    // You can now run your loop

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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