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

Laravel Eloquent with()中take()无法按分类加载指定数量关联记录

解决Laravel 10 Eloquent预加载关联时take()仅生效于第一个分类的问题

问题原因

你当前的写法之所以只给第一个分类加载6篇文章,是因为Eloquent的预加载逻辑:先查询所有分类,再执行一条SELECT * FROM articles WHERE category_id IN (分类ID列表) LIMIT 6的语句。这里的LIMIT 6是对整个关联查询结果集取前6条,而非每个分类单独取6条,所以这些结果基本都会属于ID最小的那个分类,其他分类自然拿不到关联数据。

解决方案

下面提供三种可行的解决方式,你可以根据项目的数据库环境和性能需求选择:

方法1:自定义关联(兼容性好)

在Category模型中定义一个新的关联方法,通过子查询实现每个分类取最多6篇文章:

// Category.php
public function limitedArticles()
{
    return $this->hasMany(Article::class)->whereIn('id', function ($query) {
        $query->select('id')
            ->from('articles')
            ->whereColumn('category_id', 'categories.id')
            ->orderBy('created_at', 'desc') // 可根据需求调整排序字段
            ->take(6);
    });
}

使用时直接调用这个新关联:

$categories = Category::with('limitedArticles')->get()->toArray();

方法2:集合处理(简单直观,适合分类数量少的场景)

先获取所有分类,再逐个加载对应分类的前6篇文章。注意:这种方式会触发N+1查询,分类数量多的时候不推荐使用:

$categories = Category::get()->map(function ($category) {
    $category->articles = $category->articles()->take(6)->get();
    return $category;
})->toArray();

方法3:窗口函数(效率最高,需数据库支持)

如果你的数据库支持窗口函数(如MySQL 8+、PostgreSQL),可以用一次查询完成所有分类的关联数据获取,性能最优:

use Illuminate\Support\Facades\DB;

$categories = Category::query()
    ->select('categories.*')
    ->joinSub(
        function ($query) {
            $query->select(
                'articles.*',
                DB::raw('ROW_NUMBER() OVER (PARTITION BY category_id ORDER BY created_at DESC) as rn')
            )->from('articles');
        },
        'filtered_articles',
        'categories.id',
        '=',
        'filtered_articles.category_id'
    )
    ->where('filtered_articles.rn', '<=', 6)
    ->get()
    ->groupBy('id')
    ->map(function ($group) {
        $category = $group->first();
        $category->articles = $group->pluck('filtered_articles')->flatten();
        return $category;
    })
    ->values()
    ->toArray();

总结

  • 若数据库版本较低,优先选方法1;
  • 分类数量少、追求代码简洁选方法2;
  • 追求性能且数据库支持窗口函数选方法3。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:15:17