假设我们有4个帖子和4个类别。
+----+--------+
| ID | Post |
+----+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
| 4 | Test 4 |
+----+--------+
+----+------------+
| ID | Category |
+----+------------+
| 1 | Category 1 |
| 2 | Category 2 |
| 3 | Category 3 |
| 4 | Category 4 |
+----+------------+
+--------+------------------------+
| Post | Category |
+--------+------------------------+
| Test 1 | Category 1, Category 2 |
| Test 2 | Category 2 |
| Test 3 | Category 3 |
| Test 4 | Category 4 |
+--------+------------------------+
如果我正确理解了你的问题,你想
Test 1
post使用
category__not_in
参数查询的参数如下所示:
$args = array(
\'category__not_in\' => array(2, 3, 4)
);
问题在于
category__not_in
是它产生的
NOT IN SELECT
SQL查询。
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
WHERE 1=1
AND (wp_posts.ID NOT IN
( SELECT object_id
FROM wp_term_relationships
WHERE term_taxonomy_id IN (2, 3, 4) ))
AND wp_posts.post_type = \'post\'
AND (wp_posts.post_status = \'publish\'
OR wp_posts.post_status = \'private\')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC LIMIT 0, 10
NOT IN SELECT
将排除所有帖子,包括
Test 1
. 如果这个SQL使用
JOIN
而不是
NOT IN SELECT
这将起作用。
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
WHERE 1=1
AND (wp_term_relationships.term_taxonomy_id NOT IN (2, 3, 4))
AND wp_posts.post_type = \'post\'
AND (wp_posts.post_status = \'publish\'
OR wp_posts.post_status = \'private\')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC LIMIT 0, 10
以上SQL将仅返回
Test 1
邮递我们可以使用WP\\u查询类来生成这样的查询。而不是使用
category__not_in
参数替换为
category__in
参数和添加
post_where
将根据我们的目的直接修改SQL的筛选器。
function wp_286618_get_posts() {
$query = new WP_Query( array(
\'post_type\' => \'post\',
\'category__in\' => array( 2, 3, 4 ) // Use `category__in` to force JOIN SQL query.
) );
return $query->get_posts();
}
function wp_286618_replace_in_operator($where, $object) {
$search = \'term_taxonomy_id IN\'; // Search IN operator created by `category__in` parameter.
$replace = \'term_taxonomy_id NOT IN\'; // Replace IN operator to NOT IN
$where = str_replace($search, $replace, $where);
return $where;
}
add_filter( \'posts_where\', \'wp_286618_replace_in_operator\', 10, 2 ); // Add filter to replace IN operator
$posts = wp_286618_get_posts(); // Will return only Test 1 post
remove_filter( \'posts_where\', \'wp_286618_replace_in_operator\', 10, 2 ); // Remove filter to not affect other queries
与其他解决方案相比,此解决方案的优点是我不需要知道其他类别的ID,它将保持您的post循环干净。