İstediğiniz şey mümkün, ancak mümkün olduğunca kaçınmak istediğim SQL'e girmenizi gerektirecek (bilmiyorum, çünkü gelişmiş bir SQL geliştiricisiyim, ancak WordPress'te mümkün olduğunca API kullanmak istiyorsunuz gelecekteki olası veritabanı yapısı değişiklikleriyle ilgili gelecekteki uyumluluk sorunlarını en aza indirmek.)
UNION
Operatörlü SQL Bir Olasılıktır
Bir ihtiyacım olan SQL kullanmak için UNION
, sorgunuzdaki operatör bu kategori salyangozlar varsayarak böyle bir şey vardır "category-1"
, "category-1"
ve "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'u bir posts_join
Filtre ile kullanabilirsiniz
Yukarıdakileri kullanarak sadece doğrudan arama yapabilir veya aşağıdaki gibi bir posts_join
filtre kancası kullanabilirsiniz ; not Ben bir PHP yorumlu kullanıyorum bu yüzden SQL;
sol floş olduğundan emin olun . Ayrıca, bir dizideki kategori sümüklü böcekleri listeleyerek, kanca dışındaki kategorileri tanımlamanıza izin vermek için genel bir değişken kullandığımı unutmayın. Bu kodu bir eklentiye veya temanızın functions.php
dosyasına koyabilirsiniz :
<?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 " ;
}
Ama Yan Etkiler Olabilir
Tabii ki sorgu değiştirme kancalarını posts_join
her zaman olduğu gibi kullanmak, yan etkileri davet eder ve küresel olarak sorgulara etki eder ve bu nedenle değişikliklerinizi genellikle if
yalnızca gerektiğinde kullanan ve test etmek için hangi ölçütlerin zor olabileceği bir şekilde sarmanız gerekir .
Bunun yerine Optimizasyona mı odaklanıyorsunuz?
Ancak, sorunuzun en iyi 5 zaman 3 sorgusu yapabilmekten daha fazla optimizasyonla ilgili olduğunu varsayalım , değil mi? Durum buysa, WordPress API'sini kullanan başka seçenekler de olabilir mi?
Geçici Önbellek API'sı Önbellek için Daha İyi?
Gönderilerinizin bu kadar sık değişmeyeceğini düşünüyorum, değil mi? Üç (3) sorguyu isabetli olarak periyodik olarak kabul ederseniz ve sonuçları Geçici Geçişler API'sını kullanarak önbelleğe alırsanız ne olur ? Sürdürülebilir kod ve mükemmel performans elde edersiniz; UNION
WordPress, yazı listelerini wp_options
tablonun bir kaydında serileştirilmiş bir dizi olarak saklayacağından yukarıdaki sorgudan biraz daha iyidir .
Bunu test.php
test etmek için aşağıdaki örneği alıp web sitenizin kök dizinine bırakabilirsiniz :
<?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);
özet
Evet olsa da, bir SQL UNION
sorgusu ve posts_join
filtre kancası kullanarak istediğinizi yapabilirsiniz, bunun yerine Transients API ile önbelleğe almayı kullanarak muhtemelen daha iyi teklif verebilirsiniz .
Bu yardımcı olur umarım?