Support

Account

Home Forums Front-end Issues Wp_query with relationship to another custom post type

Solving

Wp_query with relationship to another custom post type

  • Hello, I need make a query…

    I have 2 custom posts – HOSPITALS and BRANCH CLINICS. Each hospital has some unique clinics. Hospital has True/false field, when I turn it on, it became RECOMENDED. Also, all clinics conected to hospital became recomended.

    So I need a WP_query with all recomended CLINICS. Any idea?

    Thanks, Kubajjz

  • Hi @kubajjz

    Below are the arguments for a WP_Query I created recently that hopefully you can pick apart and make sense of for your use case:

    $projects_args = array(
      'post_type' => 'projects',
      'post_status' => 'publish',
      'relation' => 'AND',
      'meta_query' => array(
        array(
          'key' => 'cc_project_complete',
          'value' => FALSE,
          'compare' => '='
        ),
        array(
          'key' => 'cc_project_customer',
          'value' => $customer_id,
          'compare' => '='
        )
      ),
      'fields' => 'id, title, cc_project_job_num, cc_project_load_ship_date, cc_project_asap, cc_project_po_received_date, cc_project_dept_planned_1, cc_project_dept_planned_2, cc_project_dept_planned_3, cc_project_dept_planned_4, cc_project_dept_planned_5, cc_project_dept_planned_6, cc_project_dept_planned_7, cc_project_dept_planned_8, cc_project_dept_planned_9, cc_project_dept_planned_10, cc_project_dept_planned_11, cc_project_dept_planned_12, cc_project_dept_planned_13, cc_project_dept_planned_14, cc_project_dept_planned_15, cc_project_urgency, cc_project_asap_lead_time, cc_project_rush_lead_time, cc_project_standard_lead_time, cc_project_complete, cc_project_customer'
    );
    

    ‘cc_project_complete’ is my True/False ACF field. Also… you can decide what fields to return using ‘fields’. And in this example… I made sure that 2 criteria were satisfied by using ‘relation’ => ‘AND’ with my ‘meta_query’

    Hope that steers you in the right direction.

  • Hello @keithlock, thanks for your help. But I dont have problem with “True/False” field, I need link the_query to another post_type with relationship field. Logic of query should be like this, but meta_query doesnt support “post_type”:

    <?php
        $args = array(
            'post_type' => 'branch_clinic',
            'posts_per_page' => 10,
            'meta_query' => array(
                array(
                    'post_type' => 'hospital',
                    'key' => 'template-part-clinic-heading__highlight',
                    'value' => '1',
                ),
            ),
        );
        $the_query = new WP_Query( $args );
    ?>

    “template-part-clinic-heading__highlight” is TRUE/FALSE field in HOSPITAL post type, and this hospital is linked by relationship field to BRANCH CLINIC.

    Thanks,
    Jakub

  • Wouldn’t you query the hospitals first then?

    Example:

    1) Get all Branch IDs of all hospitals, where Recommended = TRUE
    2) Add all those IDs to an array
    3) Remove duplicates from the array of Branch IDs
    4) Query Branches with Post IDs in ( post__in ) your array

    Am I understanding correctly?

  • thanks @keithlock, but I can’t imagine how should the code looks like. Can you write an example?

    Thanks,
    Jakub

  • Sure, I will cobble some code together below. May need some tweaks 🙂

    
    $args = array(
      'post_type' => 'hospital',
      'posts_per_page' => 10, // you could use -1 for 'all'
      'meta_query' => array(
        array(
          'key' => 'recommended',
          'value' => TRUE,
          'compare' => '=',
        ),
      ),
    );
    $the_query = new WP_Query( $args );
    
    $all_branch_ids = array();
    if ( $the_query->have_posts() ) {
      while ( $the_query->have_posts() ) {
        $the_query->the_post();
          $all_branch_ids = array_merge( $all_branch_ids, get_field('branch_id_field') ); // this *should* work (untested)
      }
      wp_reset_postdata();
    }
    // Essentially, with the above, we are looping through 'hospital' records and appending the array of "branch ids" (from the relationship field) to an array of "all" bracnch ids. This *could* potentially introduce duplicates, for which we address below.
    Of course, we are only getting "branch ids" that are *recommended*, because the Hospital Query only returns recommended hospitals.
    
    $all_branch_ids = array_unique($all_branch_ids); // remove duplicates
    
    // Now, we can query branches using: post__in
    
    $args = array(
      'post_type' => 'branch_clinic',
      'posts_per_page' => -1, // use -1 for 'all'
      'post__in' => $all_branch_ids // has to be array like: array( 2, 5, 12, 14, 20 )
    );
    $the_query = new WP_Query( $args );
    

    Note that empty arrays passed to ‘post__in’ can have undesired results, and there is a special note to be made about ‘sticky posts’ when using ‘post__in’

    I encourage you read this entire page: https://codex.wordpress.org/Class_Reference/WP_Query

  • Thanks @keithlock for the code, but it doesn’t work.
    If I understand the code right – I think there is a mistake in a part “this *should* work (untested)”. The relationship field is on “Branch side”. In administration of branch – there I choose relationship to hospital.

    Am I wrong?

    Thanks for your helping

  • Ahhh, I see.. I assumed the other way around because it’s a 1 to many from hospitals to branches…

    I can’t think of the logic then.. hmmm…

    The goal is to find “recommended” branches right? And a branch is considered “recommended” if a “recommended” hospital is attached to it? Am I right so far?

    If so… and you are connecting them in the way that you are… choosing 1 hospital for each branch… then….

    I would:

    1) Create an array of all hospital IDs that *are* recommended. Hint: You can use WP_Query to return *just* the IDs.

    Here’s the info from this link:

    /// Return Fields Parameter
    Set return values.

    fields (string) – Which fields to return. All fields are returned by default. There are two other options:
    ‘ids’ – Return an array of post IDs.
    ‘id=>parent’ – Return an array of stdClass objects with ID and post_parent properties.
    Passing anything else will return all fields (default) – an array of post objects ///

    2) Then… Query branches that contain those hospital IDs… you can do a meta query such as:

    
    'meta_query' => array(
      array(
        'key' => 'hospital',
        'value' => array( 3, 4 ), // array of hospitals IDs from 1st query
        'compare' => 'IN',
      ),
    

    Cool?

  • Thanks @keithlock, we are near, but the last step is not working and I cannot figure it out. For testing I have simple query

    
    $args = array(
        'post_type' => 'branch_clinic',
        'meta_key' => 'hospital', // relationship field
        'meta_value' => '536', // ID of hospital
        'meta_compare' => '=',
    );
    

    But it is not working. If I get ID from hospital in regular query, I get right ID – 536

    
    <?php the_field('hospital'); ?>
    

    If I fill with any other fields (branch name) it works. It looks like, that Relationship field cannot be as meta_key… Or do you know, what is going on?

    ———————-

    For explanation, chech this page – http://tuaestetica.pavlovec.net – it is in Czech language, you can switch to English, but it is without data… If you click on “Kliniky” you will see all Hospitals. If you will click on hospital, you will see the detail and all branches at the bottom. In the sidebar, you can specify, which branches you looking for – select location and/or procedure. Here you will see all branches. And there should be those RECOMMENDED branches first and than others.

    ———————-

    Thanks a lot for your helping,
    Jakub

  • hi Jakub,

    Maybe try adding ‘type’ => NUMERIC to the query, or remove the quotes from the number?

  • Not working… I have tried many combinations and nothing

  • 'meta_query' => array(
      array(
        'key' => 'hospital',
        'value' => array( 3, 4 ), // array of hospitals IDs from 1st query
        'compare' => 'IN',
      ),

    Cool?

    Not cool 🙂

    This does not work in my particular case. I can query with a single ID and compare “LIKE” but not with an array of IDs and compare “IN”.

Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.