Apa yang Anda inginkan adalah mungkin tetapi akan meminta Anda mempelajari SQL yang ingin saya hindari kapan pun memungkinkan (bukan karena saya tidak mengetahuinya, saya adalah pengembang SQL tingkat lanjut, tetapi karena di WordPress Anda ingin menggunakan API bila memungkinkan untuk meminimalkan masalah kompatibilitas di masa depan terkait dengan perubahan struktur basis data potensial di masa depan.)
SQL dengan UNION
Operator adalah Kemungkinan
Untuk menggunakan SQL yang Anda butuhkan adalah UNION
operator dalam kueri Anda, sesuatu seperti ini dengan asumsi siput kategori Anda "category-1"
, "category-1"
dan "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
)
Anda dapat menggunakan SQL UNION dengan posts_join
Filter
Dengan menggunakan di atas Anda bisa langsung melakukan panggilan atau Anda dapat menggunakan posts_join
hook filter seperti berikut; perhatikan saya menggunakan PHP heredoc jadi pastikan SQL;
flush kiri. Juga perhatikan saya menggunakan var global untuk memungkinkan Anda mendefinisikan kategori di luar hook dengan mendaftar siput kategori dalam array. Anda dapat meletakkan kode ini di plugin atau di functions.php
file tema Anda :
<?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 " ;
}
Tapi Bisa Ada Efek Samping
Tentu saja menggunakan kait modifikasi permintaan seperti posts_join
selalu mengundang efek samping karena mereka bertindak secara global pada permintaan dan dengan demikian Anda biasanya perlu membungkus modifikasi Anda dalam if
yang hanya menggunakannya ketika diperlukan dan kriteria apa untuk menguji bisa rumit.
Berfokuslah pada Optimasi?
Namun, saya berasumsi bahwa pertanyaan Anda lebih menyangkut optimasi daripada tentang kemampuan melakukan permintaan 5 kali 3 teratas, bukan? Jika demikian, mungkin ada opsi lain yang menggunakan WordPress API?
Lebih baik Menggunakan API Transien untuk Caching?
Saya menganggap posting Anda tidak akan sering berubah, benar? Bagaimana jika Anda menerima tiga (3) permintaan klik secara berkala dan kemudian cache hasilnya menggunakan API Transients ? Anda akan mendapatkan kode yang dapat dipelihara dan kinerja hebat; sedikit lebih baik daripada UNION
permintaan di atas karena WordPress akan menyimpan daftar posting sebagai array serial dalam satu catatan wp_options
tabel.
Anda dapat mengambil contoh berikut dan memasukkannya ke root situs web Anda test.php
untuk mengujinya:
<?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);
Ringkasan
Sementara ya Anda bisa melakukan apa yang Anda minta menggunakan UNION
kueri SQL dan posts_join
kait filter yang mungkin lebih baik Anda tawarkan menggunakan caching dengan Transients API .
Semoga ini membantu?