Laravel - PopularityCount属性 - 排序依据

时间:2016-09-04 11:04:48

标签: laravel eloquent

我在排序/排序结果时遇到问题。 基本上我有帖子表,我根据有多少评论和喜欢来计算 popular_count 。问题是我也对结果进行了分页。所以 当我使用这样的东西时

$Posts->paginate(5);
$Posts->sortBy('popularity_count');
$Posts->get();

它仅针对特定页面进行排序,例如。第1页的结果与人气统计数字如:6,5,4,3,2,第二页有10,7,5,2,1。正如您所看到的,有人气 10 的帖子应该是第一页上的第一个结果。

当我尝试使用

 $Posts->orderBy('popularity_count')

它不起作用,因为我的数据库中没有这样的列。有没有可能在不使用RAW选择和加入的情况下实现我想要的东西?我的模型上有更多自定义属性。

谢谢!

编辑:

`public function getPopularityCountAttribute(){

    $comments = $this->getRelation('commentsCount');

    $likes = $this->getRelation('likesCount');


    $comments = ($comments) ? (int) $comments->comments_count : 0;

    $likes = ($likes) ? (int) $likes->likes_count : 0;

    $Result = $likes + ( $comments * 1.2 );

  return $Result;
}`

2 个答案:

答案 0 :(得分:3)

快速解决方案(在实施方面)是使用oderByRaw()

$Posts->orderByRaw("
    (
        select count(*)
        from likes
        where likes.post_id = posts.id
    ) + (
        select count(*)
        from comments
        where comments.post_id = posts.id
    ) * 1.2 DESC
");

如果您的posts表格很大,那么这将非常慢。您可以尝试使用两个连接和两个聚合创建查询,但这不会有太大变化。您想要仅获取5行并不重要 - 您需要计算"流行度"每次在DB中的每个帖子。

因此,如果性能问题,您可以创建三个新的"缓存" posts表中的列:

  • likes_count
  • comments_count
  • popularity

包含popularity列的索引。

每次插入或删除评论等时,您还需要更新相关帖子。我可能会用触发器做到这一点。

有了这个,你可以使用orderBy('popularity', 'DESC')

您还可以使用列post_popularity创建一个新表(post_id, comments_count, likes_count, popularity),以便将缓存的数据分开。但是你需要加入:

$Posts->join('post_popularity as pp', 'pp.post.id', '=', 'posts.id')
      ->orderBy(pp.popularity, 'DESC');

答案 1 :(得分:0)

您应该在获取数据之前对数据进行排序:

$Posts->orderBy('popularity_count')->paginate(5);

sortBy()之后使用paginate()时,您只会对5个项目的集合进行排序。