Параметр WP_Query post__not_in
супер-полезен, как минимум с его помощью можно исключать текущий пост, когда выводите похожие посты. Однако для высоконагруженных сайтов это может привести к моментикам с производительностью, потому что использование этого параметра исключает возможность кэширования запроса.
Вот допустим пример вывода последних постов на странице поста, но с исключением из цикла текущего поста:
$exclude_id = get_the_ID(); $args = array( 'posts_per_page' => 10, 'post_status' => 'publish', 'post__not_in' => array( $exclude_id ), ); $recent_posts = new WP_Query( $args ); echo '<h2>Свежие посты</h2>'; while( $recent_posts->have_posts() ) : $recent_posts->the_post(); the_title( '<h3><a href="' . get_permalink() . '">', '</a></h3>' ); endwhile; wp_reset_postdata();
Выглядит как лёгкое и чистое решение, не так ли? Но не спешите радоваться, ведь как раз от подобного решения мы сейчас и будем пытаться уйти.
Объясняю почему.
Дело в том, что запрос, который мы построили выше, теперь будет уникальным для каждого поста, потому что в нём будет присутствовать часть AND ID NOT IN ( '12345' )
, это по сути и ломает идею кэширования, потому что так как запрос уникальный, то и кэш будет уникальным для каждого запроса и в итоге, вместо того, чтобы всего-то получить последние посты из кэша, у нас будет происходить подключение к базе данных и полноценно вся работа.
Конечно, на обычных сайтах это не сильно нас напряжёт, но на сайтах с сотнями тысяч постов вы это точно почувствуете.
Как же мы можем переделать наш предыдущий пример в таком случае?
$exclude_id = get_the_ID(); // мы знаем, что один пост вероятно исключим, поэтому получаем не 10, а 11 $args = array( 'posts_per_page' => 11, 'post_status' => 'publish' ); $recent_posts = new WP_Query( $args ); echo '<h2>Свежие посты</h2>'; // нам понадобится счётчик, потому что не факт, что исключаемый пост будет в цикле // а значит без счётчика у нас будет выводиться то 10, то 11 – не порядок $count = 0; while( $recent_posts->have_posts() && $count < 10 ) : $recent_posts->the_post(); if( $recent_posts->post->ID === $exclude_id ) { continue; // скипаем итерацию цикла, если это исключаемый пост } the_title( '<h3><a href="' . get_permalink() . '">', '</a></h3>' ); $count++; endwhile; wp_reset_postdata();