mysql - 高效的 MySQL/Eloquent 查询通过超过 1 个标签过滤帖子

标签 mysql laravel eloquent many-to-many pivot-table

设置由两个表(线程、标签)和一个数据透视表(tag_thread)组成,以允许多对多关系:一个线程可以有多个标签,一个标签可以用于多个线程。

表格的属性:

足迹:id,title

标签:id, name

线程:id、thread_id、tag_id

现在我想使用多个标签而不是一个标签来过滤线程。所以我想获取与所有给定标签关联的所有线程?仅使用一个,我可以通过 Laravel Eloquent 使用如下模型轻松完成:

$filteredThreads = $tag->threads()->get()

我已经设法用两个标签做到了,但我觉得这是一种非常肮脏和低效的方法(特别是考虑到它遍历了整个 id 列表以进行比较):

$threadIds = Thread::select('th.id')
        ->from('threads AS th')
        ->join('tag_thread AS tt', 'tt.thread_id', 'th.id')
        ->join('tags AS ta', 'tt.tag_id', 'ta.id')
        ->where('ta.name', $tag)
        ->pluck('id')
        ->toArray();

return $filteredThreads->whereIn('threads.id', $threadIds);

你能想到更好的解决方案吗?谢谢!

最佳答案

如果您想要获得具有 $tagsNames 数组中定义的名称之一的标记的线程:

$tagsNames = ['popular', 'cool'];
Thread::whereHas('tags', function($q) use($tagsNames) {
    $q->whereIn('name', $tagsNames);
})->get();

关于mysql - 高效的 MySQL/Eloquent 查询通过超过 1 个标签过滤帖子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48281537/

相关文章:

laravel - 如何将 firebase token 传递给 Laravel 应用程序?

laravel - 如何在 Laravel-Vue.js 应用程序中使用 Storybook

php - Laravel 从 ManyToOne 关系错误 SQLSTATE [23000] 创建 Eloquent 实例

mysql - 如何在 Laravel 中创建 where 语句以匹配来自另一个模型的字段

php - 如果匹配多个类型则选择查询记录

mysql - 如何仅返回日期字段中具有最大年份的 SQL 行?

php - Laravel + Redis 通过 SSL 缓存?

mysql - Laravel 当足够n条记录时如何批量插入数据库?

mysql - 如何将 SQL 源代码转换为伪代码

php - 无法获取 AJAX 表单来提交 MySQL 数据