We had a request from one of our clients to be able to search in the admin area for a custom post type by another custom post type that are linked by an Advanced Custom Field (ACF) relationship.

This meant that the admin area search box would need to add a new search criteria for that new meta data. In this example, we have 2 custom post types - products and brands. Each product has a relationship Brand associated with it. We need to search the products for those brands.

add_action( 'pre_get_posts', 'acf_search_relationship' );
function acf_search_relationship( $q ) {
  $s = $q->get('s');
  $post_type = $q->get('post_type');

  // Be very selective when running code at the pre_get_posts hook
  if (  ! is_admin() || empty( $s ) || 'product' != $post_type  ) {
    return;
  }

  // get all brands that match the search parameter $s
  $found_brands = get_posts( array(
    'post_type' => 'brand',
    'nopaging' => true,
    'title' => $s,
    'fields' => 'ids'
  ) );
        
  // build a meta query to include all posts that contains
  // the matching brands IDs in their custom fields
  $meta_query = array('relation' => 'OR');
  foreach ( $found_brands as $artist_id ) {
    $meta_query[] = array(
      'key' => 'brand', // name of custom field
      'value' => '"'.intval($brand_id).'"',
      'compare' => 'LIKE'
    );
  }

  $q->set( 'meta_query', $meta_query );
  $q->set( 's', '' ); // unset the original query parameter to avoid errors
        
}

This modifies the query before it get's the posts by setting a new meta query. It first searches for the Brands and grabs the IDs. Then it searches for Products that have the meta data that has those IDs.