it-swarm-ko.tech

WP_Query를 사용하여 범주별로 제한된 게시물을 사용하여 여러 범주를 쿼리 하시겠습니까?

각 15 개의 게시물에 3 개의 카테고리가 있습니다. DB에 대해 각 카테고리의 첫 번째 게시물을 5 개만 가져오고 싶습니다. 어떻게해야합니까?

$q = new WP_Query(array( 'post__in' => array(2,4,8), 'posts_per_page' => **FIRST_5_OF_EACH_CAT** ));

가능하지 않은 경우, 더 효율적인 것은 무엇이며, 상위 카테고리에 대한 모든 게시물을 가져 와서 반복하거나 3 가지 다른 쿼리를 작성합니까?

10
Amit

원하는 것은 가능하지만 가능한 경우 피하고 싶은 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 heredoc 을 사용하고 있으므로 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를 사용하는 다른 옵션이 있습니까?

캐싱에 과도 API를 사용하는 것이 더 낫습니까?

귀하의 게시물이 자주 변경되지 않는다고 가정합니다. 3 개의 쿼리 적중을 주기적으로 승인 한 다음 Transients API 를 사용하여 결과를 캐시하면 어떻게 되나요? 유지 관리 가능한 코드와 뛰어난 성능을 얻을 수 있습니다. WordPress는 wp_options 테이블의 한 레코드에 일련의 배열로 게시물 목록을 저장하기 때문에 위의 UNION 쿼리보다 훨씬 좋습니다.

다음 예제를 사용하여 웹 사이트 루트에 test.php로 드롭하여이를 테스트 할 수 있습니다.

<?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 대신에.

이것이 도움이 되었습니까?

15
MikeSchinkel

WP_Query() First Cat for Each Cat 를 지원하지 않습니다. WP_Query() 대신 각 카테고리에 get_posts()을 사용하여 세 번 말할 수 있습니다.

<?php
$posts      = array():
$categories = array(2,4,8);
foreach($categories as $cat) {
  $posts[] = get_posts('numberposts=5&offset=1&category='.$cat);
}
?>

$posts에는 이제 각 카테고리에 대한 처음 다섯 개의 게시물이 있습니다.

1
hakre

단일 쿼리에서 각 범주에 대해 처음 다섯 개의 게시물을 가져올 수있는 방법을 모르겠습니다. 45 개의 게시물 만 남기고 싶다면 데이터베이스를 한 번 치고 각 카테고리에 5 개의 게시물을 올리는 것이 가장 효율적인 방법 일 것입니다. 데이터베이스를 세 번 치고 결과를 결합하는 것은 나쁜 것이 아닙니다.

0
Bernard Chen