Laravel Eloquent 按关系计数排序

Posted

技术标签:

【中文标题】Laravel Eloquent 按关系计数排序【英文标题】:Laravel Eloquent Order By Relationship Count 【发布时间】:2021-01-25 01:28:09 【问题描述】:

我有一个小型博客应用程序,它允许用户上传照片和音频。用户还可以搜索其他博客。在搜索时,我想为我的查询添加一个排名,优先级如下:

1) Users with most photos
2) Users with most audio

User 模型是这样构造的:

public function blog() 
    return $this->hasOne(Blog::class);


public function photos() 
    return $this->hasMany(Photo::class);


public function audio() 
    return $this->hasMany(Audio::class);

博客模型是这样构建的:

public function user()

    return $this->belongsTo(User::class);

我当前的搜索查询:

    $blogs = Blog::where('description', 'ilike', '%'.$search.'%')
    ->orWhere('title', 'ilike', '%'.$search.'%')
    ->orWhereHas('user', function($query) use ($search) 
        $query->where('name', 'ilike', '%'.$search.'%')
            ->orWhere('username', 'ilike', '%'.$search.'%');
    )
    ->paginate(10);

根据给定的详细信息,我如何调整我的查询以返回对我的用户照片和音频计数进行排名的博客?

** 更新 **

我可以通过使用带有预加载的withCount 方法来获取每个嵌套关系的计数:

    $blogs = Blog::where('description', 'ilike', '%'.$search.'%')
    ->orWhere('title', 'ilike', '%'.$search.'%')
    ->orWhereHas('user', function($query) use ($search) 
        $query->where('name', 'ilike', '%'.$search.'%')
            ->orWhere('username', 'ilike', '%'.$search.'%');
    )
    ->with(['user' => function($query)
        $query->withCount(['blobs', 'audio']);
    ])
    ->paginate(10);

但是,我怎样才能通过这些嵌套的计数属性对当前查询进行排序呢?

【问题讨论】:

【参考方案1】:

基于 Laravel 8 文档: https://laravel.com/docs/8.x/eloquent-relationships#counting-related-models

你可以试试:

Blog::withCount(['photos', 'audio'])

这将放置 2 列:photos_count 和 audio_count。

所以最终的结果是:

$blogs = Blog::withCount(['photos', 'audio'])
->where('description', 'ilike', '%'.$search.'%')
->orWhere('title', 'ilike', '%'.$search.'%')
->orWhereHas('user', function($query) use ($search) 
    $query->where('name', 'ilike', '%'.$search.'%')
        ->orWhere('username', 'ilike', '%'.$search.'%');
)
->orderBy('photos_count', 'desc')
->orderBy('audio_count', 'desc')
->paginate(10);

【讨论】:

感谢您对该文档的引用!不幸的是,因为photosaudio 关系在User 模型上,而不是Blog,所以这不起作用。如果您查看我更新的答案,我能够在急切加载时获取这些嵌套模型的计数 - 但我不知道如何按这些计数对查询进行排序。

以上是关于Laravel Eloquent 按关系计数排序的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent按关系表列排序

Laravel Eloquent 模型按局部列和关系模型列值排序

Laravel Eloquent:计数项目模型关系

Laravel按hasmany关系排序

Laravel Eloquent 如何根据计数获得关系总和

Laravel 6.0 Eloquent - 按日期和状态排序