我在排序/排序结果时遇到问题。 基本上我有 posts 表,并根据评论和喜欢的数量来计算 popularity_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;
}`
最佳答案
一个快速的解决方案(就实现而言)是使用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 行也没关系 - 您每次都需要计算数据库中每个帖子的“受欢迎程度”。
因此,如果性能是一个问题,您可以在 posts
表中创建三个新的“缓存”列:
点赞数
comments_count
受欢迎程度
带有流行度
列的索引。
每次插入或删除评论或点赞时,您还需要更新相关帖子。我可能会用触发器来做到这一点。
有了这个,您就可以使用 orderBy('popularity', 'DESC')
。
您还可以创建一个包含 post_id、comments_count、likes_count、popularity
列的新表 (post_popularity
),以便以物理方式分离缓存的数据。但随后您需要加入:
$Posts->join('post_popularity as pp', 'pp.post.id', '=', 'posts.id')
->orderBy(pp.popularity, 'DESC');
关于Laravel - PopityCount 属性 - 排序依据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39316220/