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

Laravel Eloquent使用with()+take()仅返回首个用户关联会议的问题

问题根源

你用with()加take(3)预加载关联时,Eloquent的执行逻辑是:先查所有用户,再跑一条SELECT * FROM meetings WHERE user_id IN (用户ID集合) LIMIT 3的关联查询——这只会返回全表中前3条匹配用户ID的会议,自然只有第一个匹配到的用户能拿到数据,其他用户的关联会议不在这3条里,就显示为空。

可行解决方案

方案1:用聚合/窗口函数(推荐,性能最优)

原生Eloquent(支持窗口函数的数据库,如MySQL 8+)

通过窗口函数按用户分组,取每组前3条会议,再关联到用户:

$users = User::query()
    ->with(['meetings' => function ($query) {
        $query->whereIn('id', function ($subQuery) {
            $subQuery->select('id')
                ->from(DB::raw('(SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn FROM meetings) AS sub_meetings'))
                ->where('rn', '<=', 3);
        })->latest();
    }])
    ->get();

MongoDB(jenssegers-mongodb)

用MongoDB的聚合管道实现关联时直接限制数量:

$users = User::raw(function ($collection) {
    return $collection->aggregate([
        [
            '$lookup' => [
                'from' => 'meetings',
                'let' => ['userId' => '$_id'],
                'pipeline' => [
                    ['$match' => ['$expr' => ['$eq' => ['$user_id', '$$userId']]]],
                    ['$sort' => ['created_at' => -1]], // 按创建时间倒序,可按需调整排序字段
                    ['$limit' => 3]
                ],
                'as' => 'meetings'
            ]
        ]
    ]);
});

方案2:模型定义关联+延迟加载(适用于用户量少的场景)

先在User模型里新增一个带限制的关联方法:

public function latestThreeMeetings()
{
    return $this->hasMany(Meeting::class)->latest()->take(3);
}

然后遍历用户,手动给每个用户加载关联数据:

$users = User::all()->map(function ($user) {
    $user->setRelation('meetings', $user->latestThreeMeetings()->get());
    return $user;
});

注意:这种方法会触发N+1查询(每个用户对应一条会议查询),用户数量多的时候性能会受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:40:21