Những gì bạn muốn là có thể nhưng sẽ yêu cầu bạn đào sâu vào SQL mà tôi muốn tránh bất cứ khi nào có thể (không phải vì tôi không biết, tôi là nhà phát triển SQL nâng cao, nhưng vì trong WordPress bạn muốn sử dụng API bất cứ khi nào có thể để giảm thiểu các vấn đề tương thích trong tương lai liên quan đến thay đổi cấu trúc cơ sở dữ liệu tiềm năng trong tương lai.)
SQL với một UNION
toán tử là một khả năng
Để sử dụng SQL những gì bạn cần là một UNION
nhà điều hành trong truy vấn của bạn, một cái gì đó như thế này giả sử sên loại của bạn "category-1"
, "category-1"
và "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
)
Bạn có thể sử dụng SQL UNION với posts_join
Bộ lọc
Sử dụng ở trên, bạn có thể thực hiện cuộc gọi trực tiếp hoặc bạn có thể sử dụng posts_join
móc lọc như sau; lưu ý Tôi đang sử dụng một heredoc PHP vì vậy hãy chắc chắn rằng SQL;
nó đang bị bỏ lại. Cũng lưu ý rằng tôi đã sử dụng một var toàn cục để cho phép bạn xác định các danh mục bên ngoài hook bằng cách liệt kê các sên danh mục trong một mảng. Bạn có thể đặt mã này trong một plugin hoặc trong functions.php
tệp chủ đề của bạn :
<?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 " ;
}
Nhưng có thể có tác dụng phụ
Tất nhiên, sử dụng các móc sửa đổi truy vấn như posts_join
luôn luôn mời các hiệu ứng phụ trong đó chúng tác động toàn cầu lên các truy vấn và do đó bạn thường cần phải sửa đổi các sửa đổi của mình trong một if
chỉ sử dụng nó khi cần thiết và tiêu chí nào để kiểm tra có thể khó khăn.
Tập trung vào tối ưu hóa thay thế?
Tuy nhiên, tôi cho rằng câu hỏi của bạn quan tâm là về tối ưu hóa hơn là có thể thực hiện truy vấn 5 lần 3 hàng đầu, phải không? Nếu đó là trường hợp thì có lẽ có các tùy chọn khác sử dụng API WordPress?
Sử dụng API tạm thời tốt hơn cho bộ nhớ đệm?
Tôi cho rằng bài viết của bạn sẽ không thay đổi thường xuyên, đúng không? Điều gì xảy ra nếu bạn chấp nhận ba (3) truy vấn được truy cập định kỳ và sau đó lưu trữ kết quả bằng API Transents ? Bạn sẽ nhận được mã duy trì và hiệu suất tuyệt vời; tốt hơn một chút so với UNION
truy vấn ở trên vì WordPress sẽ lưu trữ danh sách các bài đăng dưới dạng một mảng được tuần tự hóa trong một bản ghi của wp_options
bảng.
Bạn có thể lấy ví dụ sau và thả vào thư mục gốc của trang web test.php
để kiểm tra điều này:
<?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);
Tóm lược
Mặc dù có, bạn có thể thực hiện những gì bạn đã yêu cầu khi sử dụng UNION
truy vấn SQL và posts_join
hook bộ lọc mà bạn có thể cung cấp tốt hơn bằng cách sử dụng bộ đệm ẩn với API Transents thay thế.
Hi vọng điêu nay co ich?