你想要的是可能的,但需要你深入研究SQL which I like to avoid whenever possible (不是因为我不知道,我是一名高级SQL开发人员,而是因为in WordPress you want to use the API whenever possible 尽量减少与未来潜在数据库结构更改相关的未来兼容性问题。)
带有UNION
运算符可以使用SQL,您需要的是UNION
在您的查询中,假设您的类别slug是"category-1"
, "category-1"
和"category-3"
:
SELECT * FROM wp_posts WHERE ID IN (
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy=\'category\' AND t.slug=\'category-1\'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy=\'category\' AND t.slug=\'category-2\'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy=\'category\' AND t.slug=\'category-3\'
LIMIT 5
)
可以将SQL UNION与
posts_join
使用上面的过滤器,您可以
just make the call directly 或者你可以
use a posts_join
filter hook 如下所示:;注意,我使用的是
PHP heredoc 所以要确保
SQL;
左对齐。还请注意,我使用了一个全局变量,通过在数组中列出类别slug,可以定义钩子之外的类别。您可以将此代码放入插件或主题的
functions.php
文件:
<?php
global $top_5_for_each_category_join;
$top_5_for_each_category_join = array(\'category-1\',\'category-2\',\'category-3\');
add_filter(\'posts_join\',\'top_5_for_each_category_join\',10,2);
function top_5_for_each_category_join($join,$query) {
global $top_5_for_each_category_join;
$unioned_selects = array();
foreach($top_5_for_each_category_join as $category) {
$unioned_selects[] =<<<SQL
SELECT object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy=\'category\' AND t.slug=\'{$category}\'
LIMIT 5
SQL;
}
$unioned_selects = implode("\\n\\nUNION\\n\\n",$unioned_selects);
return $join . " INNER JOIN ($unioned_selects) categories ON wp_posts.ID=categories.object_id " ;
}
但是使用查询修改挂钩当然会有副作用
posts_join
总是会带来副作用,因为它们对查询起全局作用,因此您通常需要将修改打包到
if
只有在需要时才使用它,测试标准可能很棘手。
而是专注于优化
然而,我想你的问题是
more about optimization 比能够进行前5次3次查询要好得多,对吗?如果是这样,那么可能还有其他使用WordPress API的选项?
更好地使用瞬态API进行缓存
我想你的帖子不会经常改变,对吧?如果您定期接受三(3)次查询命中,然后使用
Transients API? 您将获得可维护的代码和出色的性能;比
UNION
因为WordPress将把帖子列表作为序列化数组存储在
wp_options
桌子
您可以采用以下示例,并将其作为test.php
要对此进行测试,请执行以下操作:
<?php
$timeout = 4; // 4 hours
$categories = array(\'category-1\',\'category-2\',\'category-3\');
include "wp-load.php";
$category_posts = get_transient(\'top5_posts_per_category\');
if (!is_array($category_posts) || count($category_posts)==0) {
echo "Hello Every {$timeout} hours!";
$category_posts = array();
foreach($categories as $category) {
$posts = get_posts("post_type=post&numberposts=5&taxonomy=category&term={$category}");
foreach($posts as $post) {
$category_posts[$post->ID] = $post;
}
}
set_transient(\'top5_posts_per_category\',$category_posts,60*60*$timeout);
}
header(\'Content-Type:text/plain\');
print_r($category_posts);
虽然是的,但您可以使用SQL执行您要求的操作
UNION
查询和
posts_join
您可能会更好地提供使用缓存的过滤器挂钩
Transients API 相反
希望这有帮助?