Bài viết có ít nhất 3 thẻ của danh sách các thẻ


13

Ví dụ, có các thẻ { foo, bar, chocolate, mango, hammock, leaf}

Tôi muốn tìm tất cả các bài viết có ít nhất 3 trong số các thẻ này .

Một bài với các thẻ { foo, mango, vannilla, nuts, leaf} sẽ phù hợp với nó bởi vì nó có { foo, mango, leaf} - vì vậy ít nhất 3 thẻ từ tập cần thiết của thẻ.

Do đó, nó sẽ nằm trong danh sách các bài viết phù hợp.

Có một cách đơn giản để làm điều đó, mà không cần thực hiện nhiều vòng qua tất cả các bài viết?

Câu trả lời:


8

Câu trả lời dưới đây được đơn giản hóa và có thể được mở rộng để kiểm tra xem bài đăng nào có 3 thẻ phù hợp hay không trước khi xuất danh sách. Sử dụng một truy vấn và giả sử bạn có ít nhất một bài đăng với 3 thẻ phù hợp:

//List of tag slugs
$tags = array('foo', 'bar', 'chocolate', 'mango', 'hammock', 'leaf');

$args = array(
    'tag_slug__in' => $tags
    //Add other arguments here
);

// This query contains posts with at least one matching tag
$tagged_posts = new WP_Query($args);

echo '<ul>';
while ( $tagged_posts->have_posts() ) : $tagged_posts->the_post();
   // Check each single post for up to 3 matching tags and output <li>
   $tag_count = 0;
   $tag_min_match = 3;
   foreach ( $tags as $tag ) {
      if ( has_tag( $tag ) && $tag_count < $tag_min_match ) {
         $tag_count ++;
      }
   }
   if ($tag_count == $tag_min_match) {
      //Echo list style here
      echo '<li><a href="'. get_permalink() .'" title="'. get_the_title() .'">'. get_the_title() .'</a></li>';
   }
endwhile;
wp_reset_query();
echo '</ul>';

EDIT: Điều chỉnh biến $tag_min_matchsẽ đặt số lượng khớp.


2

Đây là một cách để làm điều đó:

Cho một bộ 5 thẻ , {a, b, c, d, e}:

1) Trong PHP, tạo tất cả các tập hợp con có thể chứa 3 phần tử, không lặp lại:

{a, b, c}
{a, b, d}
{a, b, e}
{a, c, d}
{a, c, e}
{b, c, d}
{b, c, e}
{c, d, e}

2) Chuyển đổi các tập hợp con đó thành một truy vấn phân loại lớn:

$q = new WP_Query( array(
  'tax_query' => array(
    'relation' => 'OR',
    array(
      'terms' => array( 'a', 'b', 'c' ),
      'field' => 'slug',
      'operator' => 'AND'
    ),
    array(
      'terms' => array( 'a', 'b', 'd' ),
      'field' => 'slug',
      'operator' => 'AND'
    ),
    ...
  )
) );

1

Cách tiếp cận của spclldr là cách tôi đã sử dụng. Đối với vòng lặp while, đây là những gì tôi đã sử dụng thay thế:

$relatedPosts = $tagged_posts->posts;
$indexForSort = array();

for ($i = count($relatedPosts) - 1; $i >= 0; $i--) {
  $relatedPostTags = get_tags($relatedPosts[$i]->ID);
  //get the ids of each related post
  $relatedPostTags = $this->my_array_column($relatedPostTags, 'term_id');
  $relatedPostTagsInPostTag = array_intersect($tags, $relatedPostTags);
  $indexForSort[$i] = count($relatedPostTagsInPostTag);
}

//sort by popularity, using indexForSort
array_multisort($indexForSort, $relatedPosts, SORT_DESC);

Sau đó tôi lấy các bài viết hàng đầu:

$a_relatedPosts = array_slice($relatedPosts, 0, $this->numberRelatedPosts);

my_array_column là một chức năng tương tự như mảng_column của PHP 5,5:

  protected function my_array_column($array, $column) {
    if (is_array($array) && !empty($array)) {
      foreach ($array as &$value) {
        //it also get the object's attribute, not only array's values
        $value = is_object($value) ? $value->$column : $value[$column];
      }
      return $array;
    }
    else
      return array();
  }

Nó không trả lời câu hỏi ban đầu (nhưng nó giải quyết vấn đề gốc của tôi ), như: nếu không có bài viết liên quan với 3 thẻ phổ biến, thì tất cả sẽ cùng đưa ra một số bài đăng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.