You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eloquent ORM中多对多关系的交集查询与分页实现

解决多对多关联下同时匹配多个分类的Eloquent查询及分页需求

没问题,我来帮你搞定这个需求~针对多对多关联中筛选同时拥有多个指定分类的内容,再结合分页功能,用Eloquent ORM可以很优雅地实现,下面分步骤说明:

1. 先确保模型关联定义正确

首先,在Content模型中定义与Genre模型的多对多关联(中间表是content_genres):

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Content extends Model
{
    public function genres()
    {
        // 参数依次是关联模型、中间表名、当前模型外键、关联模型外键
        return $this->belongsToMany(Genre::class, 'content_genres', 'content_id', 'genre_id');
    }
}

对应的Genre模型也可以定义反向关联(可选,但便于后续其他查询):

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Genre extends Model
{
    public function contents()
    {
        return $this->belongsToMany(Content::class, 'content_genres', 'genre_id', 'content_id');
    }
}

2. 核心查询:筛选同时拥有genre_id=1和2的内容并分页

这里的关键是要确保内容同时关联两个指定分类,而不是只关联其中一个。用Eloquent的whereHas方法可以轻松实现,再链式调用paginate完成分页:

// 从Content模型出发查询
$filteredContents = Content::query()
    ->whereHas('genres', function ($query) {
        // 指定要匹配的分类ID
        $query->whereIn('genre_id', [1, 2]);
    }, '=', 2) // 第三个参数要求关联的分类记录数必须等于2(即同时匹配两个分类)
    ->paginate(10); // 10是每页显示的条数,可根据需求调整

补充:另一种原生风格的写法(供参考)

如果你更习惯用join的方式,也可以这样写,逻辑是一致的:

$filteredContents = Content::query()
    ->join('content_genres', 'contents.id', '=', 'content_genres.content_id')
    ->whereIn('content_genres.genre_id', [1, 2])
    ->groupBy('contents.id')
    // 确保匹配的不同分类数量等于2
    ->havingRaw('COUNT(DISTINCT content_genres.genre_id) = 2')
    ->select('contents.*') // 只选择content表的字段,避免重复
    ->paginate(10);

3. 分页的使用

paginate方法会自动处理前端传递的page参数,返回的$filteredContents是LengthAwarePaginator实例,你可以直接在视图中渲染分页链接(以Laravel Blade为例):

{{ $filteredContents->links() }}

这样就完成了同时匹配多个分类的内容查询,还自带分页功能啦~

内容的提问来源于stack exchange,提问作者user9074882

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:51:49