Posting dengan setidaknya 3 tag dari daftar tag

13

Sebagai contoh, ada tag { foo, bar, chocolate, mango, hammock,leaf }

Saya ingin menemukan semua posting dengan setidaknya 3 tag ini .

Sebuah posting dengan tag { foo, mango, vannilla, nuts, leaf} akan cocok karena memiliki { foo, mango,leaf } - jadi setidaknya 3 tag dari himpunan dibutuhkan tag.

Karena itu akan ada dalam daftar posting yang cocok.

Apakah ada cara sederhana untuk melakukan itu, tanpa melakukan banyak loop melalui semua posting?

Cedric
sumber

Jawaban:

8

Jawaban di bawah ini disederhanakan, dan dapat diperluas untuk memeriksa apakah ada tulisan yang memiliki 3 tag yang cocok sebelum menghasilkan daftar. Menggunakan satu permintaan dan dengan asumsi Anda memiliki setidaknya satu posting dengan 3 tag yang cocok:

//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: Menyesuaikan variabel $tag_min_matchakan mengatur jumlah kecocokan.

stellarcowboy
sumber
2

Inilah satu cara untuk melakukannya:

Mengingat satu set 5 tag, {a, b, c, d, e}:

1) Dalam PHP, buat semua himpunan bagian yang mungkin berisi 3 elemen, tanpa pengulangan:

{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) Ubah himpunan bagian itu menjadi permintaan taksonomi besar:

$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'
    ),
    ...
  )
) );
scribu
sumber
1

Pendekatan sprclldr adalah yang saya gunakan. Adapun loop sementara, inilah yang saya gunakan sebagai gantinya:

$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);

Saya kemudian mengambil posting teratas:

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

my_array_column adalah fungsi yang mirip dengan array_column 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();
  }

Itu tidak menjawab pertanyaan awal (tapi itu menyelesaikan masalah root saya ), seperti: jika tidak ada posting terkait dengan 3 tag umum, maka ini semua akan sama-sama memberikan beberapa posting.

Cedric
sumber