То, что вы хотите, возможно, но потребует от вас углубления в SQL, которого я хотел бы избегать всякий раз, когда это возможно (не потому, что я этого не знаю, я продвинутый разработчик SQL, а потому, что в WordPress вы хотите использовать API, когда это возможно минимизировать будущие проблемы совместимости, связанные с будущими потенциальными изменениями структуры базы данных.)
SQL с UNION
оператором - это возможность
Чтобы использовать SQL , что вам нужно , это UNION
оператор в запросе, что - то вроде этого предполагается , что ваши слизни категории "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
фильтром
Используя вышеупомянутое, вы можете либо просто сделать вызов напрямую, либо использовать posts_join
фильтр-ловушку, как показано ниже; Заметьте, я использую PHP heredoc, поэтому убедитесь, что SQL;
он слева. Также обратите внимание, что я использовал глобальную переменную, чтобы позволить вам определять категории вне ловушки, перечисляя слагов категорий в массиве. Вы можете поместить этот код в плагин или в 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
тот, который использует их только при необходимости, и какие критерии для проверки могут быть сложными.
Вместо этого сосредоточиться на оптимизации?
Тем не менее, я предполагаю, что ваш вопрос касается скорее оптимизации, чем возможности выполнения топ-5 запроса по времени 3, верно? Если это так, то, возможно, есть другие варианты, которые используют API WordPress?
Лучше использовать переходный API для кэширования?
Я предполагаю, что ваши сообщения не будут меняться так часто, верно? Что если вы периодически принимаете три (3) запроса, а затем кэшируете результаты с помощью API Transients ? Вы получите поддерживаемый код и отличную производительность; это немного лучше, чем 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
фильтр-хук, но вам, вероятно, лучше предложить использовать кеширование с помощью Transient API .
Надеюсь это поможет?