【问题标题】:Get count of related model in laravel获取laravel中相关模型的数量
【发布时间】:2020-03-22 06:52:53
【问题描述】:

假设我需要获得一个包含评论数的帖子。当然有很多方法可以做到这一点。这样做的最佳(或首选)方法是什么?

  1. Eager Load + 然后与路由模型绑定以在将模型注入路由时获取计数。
class Post extends Model {

    protected $withCount = [ 'comments' ];

    public function comments() 
    { 
         return $this->hasMany();
    }

}
Route::get('/posts/{post}', function (App\Post $post) {

    return $post;  // $post→comments_count gives count.

} 
  1. 缓存计数
public function getCachedCommentsCountAttribute()
{
    return Cache::remember($this->getTable() . '.' . $this->getKey() . '.comments_count', 60*60*24, function () {
        return $this->comments()->count();  // posts.{id}.comments_count
    }); 
}

  1. 其他

最好的性能是什么?

【问题讨论】:

    标签: laravel eloquent laravel-query-builder


    【解决方案1】:

    为什么不两者兼而有之?
    您可以将计数缓存更短的时间,然后,当缓存过期时,只需执行查询即可获取更新的计数。

    您还可以通过使用Eloquent Observers 永久缓存计数并仅在插入或删除评论时使缓存无效来稍微调整此方法。如果你知道你只会使用 Eloquent 方法来插入或删除评论,就可以使用它。例如,如果您执行批量插入或执行原始查询以删除评论,则不会触发事件。

    【讨论】:

    • 如何同时使用这两种方法?通过在 getCachedCommentsCountAttribute() 中使用 $this→withCount('cmets') 而不是关系?急切加载然后通过 cmets() 关系会更好吗?
    • 关于使缓存失效,我正在考虑向模型添加一个 touches 属性,并将时间戳作为键的一部分,以便在创建或更新评论时运行再次查询
    • 您可以在 Post 模型上添加一个 getCommentsCount() 方法,如果已经有 cmets 计数,它将首先检查缓存。否则它只是加载关系并获取计数,将其存储在缓存中,以便下次使用。如果您只是编辑评论,则无需触摸缓存,因为计数无法更改。
    猜你喜欢
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-26
    • 2016-08-30
    • 2014-12-05
    • 1970-01-01
    • 2014-02-12
    • 2019-02-03
    相关资源
    最近更新 更多