あなたが望むものは可能ですが、可能な限り回避したいSQLを掘り下げる必要があります(私はそれを知らないからではなく、私はSQLの上級開発者ですが、WordPressではAPIを可能な限り使用したいため将来起こり得るデータベース構造の変更に関連する将来の互換性の問題を最小限に抑えるため。)
UNION
演算子付きSQL は可能性があります
あなたが必要なもの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
)
posts_join
フィルターでSQL UNIONを使用できます
上記を使用すると、直接呼び出すか、次のようにフィルターフックを使用posts_join
できます。私が使用している注意PHPのヒアドキュメントを必ずそうで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のクエリを実行できることよりも、最適化についての懸念があると思いますか?その場合は、WordPress APIを使用する他のオプションがあるでしょうか?
キャッシュにTransients APIを使用する方が良いですか?
あなたの投稿はそれほど頻繁に変更されないと思いますが、正しいですか?3つのクエリヒットを定期的に受け入れ、Transients APIを使用して結果をキャッシュするとどうなりますか?保守可能なコードと優れたパフォーマンスが得られます。UNION
WordPressは投稿のリストをシリアル化された配列としてwp_options
テーブルの1つのレコードに格納するため、上記のクエリよりも少し優れています。
次の例を使用して、test.php
これをテストするためにWebサイトのルートにドロップできます。
<?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
フィルターフックを使用して要求したことを実行できますが、代わりにTransients APIを使用してキャッシュを使用することをお勧めします。
お役に立てれば?