你好@George:
根据您的数据库中预计有多少音乐家,如果您想要拥有大量音乐家(数千?),您可以选择完整的API路线(这通常是首选的,只要可行)您可以使用一些自定义SQL来精确地提取所需的记录。
使用WordPress API方法,WordPress API方法的基础是首先调用wp_get_object_terms()
具有$post->ID
您的个人资料音乐家和\'locations\'
将返回对象列表的分类法(不幸的是,您需要它仅位于一个位置,否则此解决方案将崩溃。但忽略此…)
接下来,您获取第一个学期的学期ID,并将其与您的\'locations\'
分类法到get_objects_in_term()
它返回一个post ID数组,其中包含与所需分类相关联的术语(注意这将包括ALL 具有ANY 与您的\'locations\'
分类法,这就是为什么这种方法只适用于少数记录。)
然后创建一个WP_Query
对象向其传递一个使用post__in
按您在上面收到的音乐家ID列表以及您的\'locations\'
分类法及其特定的城市术语是为您的个人资料音乐家捕获的。当然,您还必须记住使用\'post__not_in\'
论点
综上所述,我将该逻辑打包为一个函数,名为get_posts_related_by_taxonomy()
您可以在这里看到其源代码(我在解释时省略了一些细节,但希望它们相当明显):
function get_posts_related_by_taxonomy($post_id,$taxonomy,$args=array()) {
$query = new WP_Query();
$terms = wp_get_object_terms($post_id,$taxonomy);
if (count($terms)) {
// Assumes only one term for per post in this taxonomy
$post_ids = get_objects_in_term($terms[0]->term_id,$taxonomy);
$post = get_post($post_id);
$args = wp_parse_args($args,array(
\'post_type\' => $post->post_type, // The assumes the post types match
\'post__in\' => $post_ids,
\'post__not_in\' => $post->ID,
\'taxonomy\' => $taxonomy,
\'term\' => $terms[0]->slug,
));
$query = new WP_Query($args);
}
return $query;
}
现在您可以在中使用此函数
your own loop 像这样:
// This assumes that your musician profile record is in the $post variable
$musicians = get_posts_related_by_taxonomy($post->ID,\'locations\');?>
<ul>
<?php while ($musicians->have_posts()): $musicians->the_post(); ?>
<li><?php the_id(); ?> -- <?php the_title(); ?></li>
<?php endwhile; ?>
</ul>
使用直接SQL方法正如我已经说过的,如果可行的话,我更喜欢WordPress API。不幸的是,我认为如果你有相当多的音乐家,并且使用上面所示的方法,你会遇到演奏或记忆问题。
作为一种性能和内存高效的替代方法,您可以使用直接SQL来替换调用get_objects_in_terms()
在前面的示例中。好消息是,SQL很简单,不太可能在将来遇到新版本WordPress的兼容性问题,因为SQL只引用主键和外键,除非它们彻底修改分类系统,否则不会改变,我认为这是不可能的。
使用SQL,我创建了get_posts_related_by_taxonomy()
调用与第一个版本完全相同的函数。SQL识别表wp_term_relationships
只是需要通过共同的term_taxonomy_id
字段,该字段将关联给定位置的所有音乐家记录//em>(分类法)+城市//em>(术语)对。然后我们把它加入wp_term_taxonomy
表,以便我们可以在分类法上进行筛选,我们还可以按关系一端的已配置音乐家进行筛选,并进行筛选以确保没有任何相关音乐家是关系另一端的已配置音乐家。我们最终确保相关的音乐家帖子类型与我们分析的音乐家帖子类型相同,这样您就可以避免再次查找,在这种情况下,我们避免调用get_post()
.
我们从SQL得到的结果是一个简单的post ID数组,我们可以再次使用post__in
争论WP_Query
但这次我们不需要包括post__not_in
, taxonomy
或term
滤器$args
我们可以知道post_type
使用\'any\'
因为我们的SQL查询已经处理了所有这些。
对于第二个版本,以下是您需要的代码:
function get_posts_related_by_taxonomy($post_id,$taxonomy,$args=array()) {
global $wpdb;
$sql =<<<SQL
SELECT
related.object_id
FROM
{$wpdb->term_relationships} post
INNER JOIN {$wpdb->term_taxonomy} link ON post.term_taxonomy_id = link.term_taxonomy_id
INNER JOIN {$wpdb->term_relationships} related ON post.term_taxonomy_id = related.term_taxonomy_id
WHERE 1=1
AND link.taxonomy=\'%s\'
AND post.object_id=%d
AND post.object_id<>related.object_id
AND post.post_type==related.post_type
SQL;
$post_ids = $wpdb->get_col($wpdb->prepare($sql,$taxonomy,$post_id));
$args = wp_parse_args($args,array(
\'post_type\' => \'any\',
\'post__in\' => $post_ids,
));
return new WP_Query($args);
}
同样,您将使用
get_posts_related_by_taxonomy()
与您使用第一个版本的方式完全相同。
希望这有帮助!