0

How can I consolidate the queries below... ?

Query 1: Any posts with the "Topic" taxonomy term, eg. "Music"

Query 2: Any posts attached to a "Company" taxonomy term, eg. "Spotify", which itself has the above "Topic" term, eg. "Music" (via meta field 'org_topics').

The result should be all "Music"-related posts, whether it is a post directly tagged with that Topic or a post whose attached Company has that Topic.

Query 1, regular:

  $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
  $query_args = array(
  // pagination
    'nopaging' => false,
    'posts_per_page' => 81,
    'paged' => $paged,
    // order
    'order_by' => 'date',
    'order'   => 'DESC',
    // posts
    'post_type' => 'any',
    // taxonomies
    'tax_query' => array(
      'relation' => 'AND',
      array(
        'taxonomy' => 'topic',
        'field'    => 'slug',
        'terms'    => 'music,
        'include_children' => false,
      ),
   ),
  );
  global $query_posts;
  $query_posts = new WP_Query($query_args);
  wp_reset_postdata();

Query 2, more complex:

I already have a custom function (get_posts_with_extras) which does this query in isolation.

It calls a prior custom function (get_terms_with_extras) which first gets a list of terms with matching meta. We use that to generate an array of term IDs to pre-set in WP_Query.

$post_results = get_posts_with_tax_and_meta('any', 'company', array('org_topics'=>$queried_object->term_id), 81);

.

function get_posts_with_tax_and_meta(          // Get these posts...
   $post_type,                                 // 1. Get posts of this post type                        eg. 'viewpoint'
   $taxonomy,                                  // 2. But only those with this taxonomy                  eg. 'company'
   $tax_meta,                                  // 3. And the taxonomy term has this meta                eg. array('tags'=>'Marketing'),
   $num_posts=6,                               // 4. Return this many posts                             eg. 6
   $tax_and_term=null,                         // 5. Constrain by a second taxonomy and term            eg. array('format'=>'oped'),
   $offset                                     // 6. Offset posts by this number of posts               eg. 4
   // $paged                                   // 7. Pagination page
) {

  /*  1. First, get the Taxonomy Terms' IDs */
  // These are the relevant Taxonomy Term objects

  $terms_list = get_terms_with_extras(
     $taxonomy,                                // 1. Get terms in the specified taxonomy                eg. 'company'
     array(key($tax_meta)=>reset($tax_meta)),  // 2. Which also have these meta fields                  eg. array('tags'=>'media')
     $post_type,                               // 3. And also have posts of the specified type          eg. 'viewpoint'
     '',                                       // 4. But those posts must have this taxonomy and term   eg. array('format'=>'oped')
     'name',                                   // 5. Order by value, corresponds to get_terms order_by  eg. 'name'
     'asc'                                     // 6. Order direction, corresponds to get_terms order    eg. 'asc'
                                               // 7. Limit term result, corresponds to get_terms number eg. 16
 );


  // But we only want the Terms' IDs (to pass to the query below)...
  $terms_list_ids = array();
  foreach ($terms_list  as $term_single) {
       array_push($terms_list_ids, $term_single->term_id);
  }

  if ( !empty($tax_and_term) ) {
     $tax_and_term_query[] = array(
     'taxonomy' => key($tax_and_term),
     'field' => 'slug',
     'terms' => reset($tax_and_term),
     );
   } else {
     $tax_and_term_query[] = null;
   }


  /* 2. Get the Posts with those Terms */
  // Query posts
  global $paged;
  $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
  $query_args = array(
  // pagination
    'nopaging' => false,
    'posts_per_page' => $num_posts,
    'paged' => $paged,
    // order
    'order_by' => 'date',
    'order'   => 'DESC',
    // posts
    'post_type' => $post_type,
    'offset' => $offset,
    // taxonomies
    'tax_query' => array(
      'relation' => 'AND',
      array(
        'taxonomy' => $taxonomy,
        'field'    => 'id',
        'terms'    => $terms_list_ids,
        'include_children' => false,
      ),
      $tax_and_term_query,
   ),
  );
  global $the_post_results; // Make it available everywhere
  // Get the posts and return them to whatever called this...
  $the_post_results = new WP_Query($query_args);
  wp_reset_postdata();
  return $the_post_results;


}

This second query works fine in isolation.

What I don't understand is how to combine these two.

Is the right approach to perform the two queries and then combine at the end somehow? (I have tried a couple of array merging techniques, but the resulting query seems to become unstuck).

Or is there a way to make a single, more efficient query?

1 Answer 1

0

The answer is "take the array from the tax_query argument in the first query, insert it into the second and change the relation to OR".

In other words, to use a single query with the following in the arguments ...

(As stated before, $terms_list_ids was already generated; it contains the IDs of Company terms which have meta that matches the current Topic term).

Credit for the answer goes to a Reddit user.

  // taxonomies
  'tax_query' => array(
    'relation' => 'OR',
    // Posts related to a Company with this Topic...
    array(
      'taxonomy' => 'company',
      'field'    => 'id',
      'terms'    => $terms_list_ids,
      'include_children' => true, // <<< IMPORTANT
    ),
    // Or...
    // Posts with this Topic directly...
    array(
      'taxonomy' => 'topic',
      'field'    => 'slug',
      'terms'    => $topic_term->slug,
      'include_children' => false,
    ),
 ),

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.