0

I need to combine two different WordPress WP_Query Objects with separate $posts_per_page

lets say we have two different categories and each of them is responsible to show 18 posts or products of their own category, something like:

$category_query = new WP_Query([
   'posts_per_page' => '18',
    'post_type' => 'product',
    'tax_query' => [
       [
         'taxonomy' => 'product_cat',
         'terms' => 120,
         'field' => 'id',
         'include_children' => false
      ]
    ]
 ]);

Imagine Another query just like above but with a different term_id, as you can see posts_per_page is 18 and for each query 18 products with specific category will be returned.

Although it is correct, but I am trying to combine the two queries to reduce number of database queries and return the total of 36 products which the first 18 includes only category number 1 and 18 others for category number 2, even if they are in random order a simple traverse through array could fix this issue.

Do you have any idea how to do that?

0

What about just querying for both terms and increasing the posts_per_page count.

$category_query = new WP_Query([
   'posts_per_page' => 36,
    'post_type' => 'product',
    'tax_query' => [
       [
         'taxonomy' => 'product_cat',
         'terms' => [ 120, 121 ],
         'field' => 'id',
         'include_children' => false
      ]
    ]
 ]);

EDIT:

Running a query with more that one term and guarantees 18 for each term ( assuming there are at least 18 items for each ) is not possible as far as I know.

My recommendation would be to run two separate queries, merge the results together and then cache that post list. This would allow you to only hit the database once the cache is invalidated.

Example: ( I've left the args out for brevity as the only thing that changes is the term id. )

// Look for the cached posts
$merged_items = get_transient( 'my_category_query' );

// If we don't have them, get and cache them
if( false === $merged_items ) {
    $cat_query_one = new WP_Query( $args_with_the_first_term );
    $cat_query_two = new WP_Query( $args_with_the_seccond_term );
    $merged_items = array_merge( $cat_query_one->posts, $cat_query_two->posts );
    set_transient( 'my_category_query', $merged_items, DAY_IN_SECONDS );
}

// Display your posts
foreach ( $merged_items as $post ) {
   // ...
}

Something to consider is that is to adjust your query to only get the post IDs using the fields => 'ids' parameter. This will make the query faster and also you can use the ID to retrieve most of the data you want to display.

Some other performance tips with WP_Query:

  • 'no_found_rows' => true: useful when pagination is not needed by not doing the calculations to determine how many post there are in total for the query.
  • 'update_post_meta_cache' => false: useful when post meta will not be utilized.
  • update_post_term_cache' => false: useful when taxonomy terms will not be utilized.

You should also be refreshing the cache when new content is added that will affect this query.

  • In this way you can get, for example, 30 results for term 121 and 6 results for term 120 instead of 18 for each term. – nmr May 15 '19 at 17:29
  • You are correct. I've updated the answer. – Welcher May 15 '19 at 20:02

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.