Home › Forums › Front-end Issues › Reverse Relationship Query
Using the Querying Relationship Fields example the documentation shows how to get..
A – All locations for a doctor
B – All doctors for a location
In this example, is it possible to have code that would return “All locations that have doctors”? I don’t care who the doctor is. I just want a list of all locations that are selected for ANY doctor.
Thanks in advance.
No, not using a single WP_Query. This would not be possible even if the relationship field was on locations instead of doctors.
Using a standard WP_Query you would need to first get ALL doctors and loop through the posts and collect a list of all of the locations from them and then do another query to get the locations.
Even using standard WP custom fields this would be difficult due to what it is you’re looking to get.
There might be some ways to reduce the number of queries, or speed things up by using $wpdb https://codex.wordpress.org/Class_Reference/wpdb to directly query the database.
Thanks John. That’s kinda what I thought. I looked into doing it directly via the database but since the relationship field is serialized data it’s a bit tricky (though I’m sure not impossible).
For anyone stumbling upon this, I was able to solve it by looping through and building an array of the info I need.
I’m using “posts” and “authors” in place of “doctors” and “locations” but the idea is the same.
$posts = get_posts(array(
'post_type' => 'post',
'posts_per_page' => -1,
'meta_key' => 'author',
'meta_value' => ' ',
'meta_compare' => '!='
));
$authors_list = array();
foreach ($posts as $post) {
$related_authors = get_field('author', $post->ID);
foreach ($related_authors as $author_id) {
if (!in_array($author_id, $authors_list)) {
$authors_list[] = $author_id;
}
}
}
function author_sort($a, $b) {
return strcmp($a->post_title, $b->post_title);
}
usort($authors_list, "author_sort");
foreach ($authors_list as $author) {
echo '<a href="' . get_the_permalink($author_id) . '">' . get_the_title($author->ID) . '</a><br />';
}
Well, If I needed I’d go directly to the database, only because it would mean a lot less queries to do and would be a lot faster. This is quick to illustrate the queries. On the other hand, I don’t think that prepare can handle the ‘IN’ clause, at least I have never found anything that gives any adequate solution.
global $wpdb;
// 1. get all the post ID's of doctors
$query = 'SELECT ID
FROM '.$wpdb->posts.'
WHERE post_type = "doctor"
AND post_status = "publish"';
$ids = $wpdb->get_col($query);
// 2. get the relationship field for all of the above posts
$query = 'SELECT meta_value
FROM '.$wpdb->postmeta.'
WHERE post_id IN ("'.implode('", "', $ids).'")
AND meta_key = "my_relationship"'; // or whatever the field name is
$list = $wpdb->get_col($query);
// 3. get list of unique locations
$location_ids = array()
for ($i=0; $<count($list); $i++) {
$value = maybe_unserialize($list[$i]);
if (is_array($value)) {
for ($j=0; $j<count($value); $j++) {
if (!in_array($value[$j], $location_ids)) {
$location_ids = intval($value[$j]);
}
} // end for j
} // end if array
} // end for i
// 4. query locations
$args = array(
'post_type' => 'location',
'posts_per_page' => -1,
'post__in' => $location_ids
);
$locations = new WP_Query($args);
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We’re reaching out to our multilingual users to ask for help in translating ACF 6.1. Help make sure the latest features are available in your language here: https://t.co/TkEc2Exd6U
— Advanced Custom Fields (@wp_acf) May 22, 2023
© 2023 Advanced Custom Fields.
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.