Laravel Eloquent 查找包含所有给定标签的帖子

Laravel Eloquent find posts that has all the given tags

考虑如下 3 tables

class Post extends Model
{
    public function tags()
    {
        return $this->belongsToMany(Tag::class, 'post_tags', 'post_id', 'tag_id');
    }

}

posts table

|id | title   |
+---+---------+
|1  |  post1  |
|2  |  post2  |
|3  |  post3  |
|4  |  post4  |

tags table

|id |  value  |
+---+---------+
|1  |  tag01  |
|2  |  tag02  |
|3  |  tag03  |
|4  |  tag04  |

post_tags table

|  post_id | tag_id  |
+----------+---------+
|     1    |    1    |
|     2    |    3    |
|     2    |    4    |
|     3    |    1    |
|     4    |    1    |
|     4    |    4    |

唯一同时具有 tag01tag04 的 post 是 post 和 id = 4

但是当我得到 posts 这个代码时

Post::whereHas('tags', function($q) {
  $q->whereIn('tag_id', [1, 4]);
}

我得到所有具有 tag01tag04 的 post。

我想获得 Posts,其中 tag01tag02 在其 tags 关系中。

如何使用 Eloquent 或如果使用 QueryBuilder

无法实现此结果

我认为你可以使用多个 where 条件

 Post::whereHas('tags', function($q) {
       $q->where('tag_id', 1);
   
    })->whereHas('tags', function($q) {
       $q->where('tag_id', 4);
   
    })->get();

如果 ID 是动态的则

$id=[1,4];
    Post::where(function($query)use($id){
        foreach ($id as $value){
            $query->whereHas('tags',function ($query)use($value){

                $query->where('tag_id',$value);


            });
        }


    })->get();

whereHas 方法需要更多参数,其中一个是计数:

Post::whereHas('tags', fn ($q) => $q->whereIn('tag_id', $tags), '=', count($tags))->get();

如果您正在寻找 [1, 4],这意味着找到所有带有标签 14 的帖子,然后只选择恰好包含其中 2 个标签的帖子(计数),这意味着找到所有具有所有这些标签的帖子。

Laravel 8.x Docs - Eloquent - Relationships - Querying Relationship Existence whereHas