To, czego chcesz, jest możliwe, ale wymaga zagłębiania się w SQL, którego lubię unikać, gdy tylko jest to możliwe (nie dlatego, że nie wiem, jestem zaawansowanym programistą SQL, ale dlatego, że w WordPress chcesz używać interfejsu API, gdy tylko jest to możliwe aby zminimalizować przyszłe problemy ze zgodnością związane z przyszłymi potencjalnymi zmianami struktury bazy danych).
SQL z UNION
operatorem to możliwość
Aby użyć SQL czego potrzebujesz to UNION
operator w zapytaniu, coś takiego zakładając kategorię ślimaki są "category-1"
, "category-1"
i "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
)
Możesz użyć SQL UNION z posts_join
filtrem
Korzystając z powyższego, możesz po prostu bezpośrednio nawiązać połączenie lub użyć posts_join
haka filtrującego w następujący sposób; Uwaga: Używam heredoc PHP, więc upewnij się, że SQL;
pozostało kolor. Zauważ też, że użyłem globalnego var, aby umożliwić ci zdefiniowanie kategorii poza hakiem, umieszczając informacje o kategorii w tablicy. Możesz umieścić ten kod we wtyczce lub w functions.php
pliku motywu :
<?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 " ;
}
Ale mogą wystąpić skutki uboczne
Oczywiście użycie haków do modyfikacji zapytań, jak posts_join
zawsze, wywołuje skutki uboczne, ponieważ działają one globalnie na zapytania, a zatem zwykle trzeba zawinąć modyfikacje w taki, if
który używa go tylko wtedy, gdy jest to potrzebne, a kryteria, które należy przetestować, mogą być trudne.
Zamiast tego skupić się na optymalizacji?
Zakładam jednak, że twoje pytanie dotyczy bardziej optymalizacji niż możliwości wykonania zapytania z 5 najlepszych czasów 3, prawda? Jeśli tak jest, to może istnieją inne opcje korzystające z interfejsu API WordPress?
Lepiej używać przejściowego interfejsu API do buforowania?
Zakładam, że twoje posty nie będą się tak często zmieniać, prawda? Co się stanie, jeśli zaakceptujesz trzy (3) trafienia kwerendy okresowo, a następnie buforujesz wyniki przy użyciu interfejsu Transients API ? Otrzymasz łatwy do utrzymania kod i doskonałą wydajność; znacznie lepiej niż UNION
powyższe zapytanie, ponieważ WordPress przechowuje listy postów jako szeregową tablicę w jednym rekordzie wp_options
tabeli.
Możesz wziąć następujący przykład i wpaść do katalogu głównego swojej witryny, test.php
aby to przetestować:
<?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);
Podsumowanie
Chociaż tak, możesz zrobić to, o co prosiłeś, używając UNION
zapytania SQL i posts_join
haka filtru, ale prawdopodobnie lepiej zaoferować użycie buforowania z Transient API .
Mam nadzieję że to pomoże?