Те, що ви хочете, можливо, але зажадає від вас заглибитись у 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;
залишився. Також зауважте, що я використовував глобальний var, щоб дозволити вам визначати категорії за межами гака, перераховуючи категорії молюсків у масиві. Ви можете помістити цей код у плагін або у 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 перехідних процесів ? Ви отримаєте бездоганний код та велику продуктивність; трохи краще, ніж 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);
Підсумок
Хоча так, ви можете виконувати те, що ви просили, використовуючи UNION
запит SQL та posts_join
гачок фільтра, ви, мабуть, краще запропонувати використовувати кешування з API Transients .
Сподіваюся, це допомагає?