Johny
Johny

Reputation: 63

Merging two post type in a single WP Query

I want to fetch the data from two different post type within a single query having different arguments for both the post type.I am using following code but how can I combine two results in a single query?

    $args = array(
        'post_type' => 'post', 
        'posts_per_page'=> '1',
    );
    $args1 = array(
        'post_type' => 'page',
        'posts_per_page'=> '3', 
    );
    $post_query = new WP_Query( $args );
    $page_query = new WP_Query( $args1 );

Upvotes: 2

Views: 6909

Answers (1)

Pieter Goosen
Pieter Goosen

Reputation: 9951

You have two options, either merge the results or run a third query. I always like the latter because then you keep the query object in place which is quite helpful for post counters and pagination.

We need to be smart here as this can really slow things down unnecessary and can become quite expensive, so this is what we will do

  • Run two very lean, very smart queries with get_posts (more optimized as a normal WP_Query as it breaks pagination which makes it faster). We will also just query the post ID's and not full objects. This will make these queries very fast and very lean. It will be almost like you never did those queries ;-)

  • Once we have the results from those queries, we can merge the ID's and run a final query to return full post objects which we can use to run a proper loop

Lets look at the code

// Set our defaults to keep our code DRY
$defaults = [
    'fields'                 => 'ids',
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
];
// Set query args for query 1
$args = [
    'post_type'      => 'post', 
    'posts_per_page' => '1',
];
// Set query args for query 2
$args1 = [
    'post_type'      => 'page',
    'posts_per_page' => '3',
];
$post_query = get_posts( array_merge( $defaults, $args  ) );
$page_query = get_posts( array_merge( $defaults, $args1 ) );

// Merge the two results
$post_ids = array_merge ( $post_query, $page_query ); //. You can swop around here

// We can now run our final query, but first mke sure that we have a valid array
if ( $post_ids ) {
    $final_args = [
        'post_type' => ['post', 'page'],
        'post__in'  => $post_ids,
        'orderby'   => 'post__in', // If you need to keep the order from $post_ids
        'order'     => 'ASC' // If you need to keep the order from $post_ids
    ];
    $loop = new WP_Query( $final_args );

    // Run your loop as normal
}

Upvotes: 8

Related Questions