我正在尝试根据相关模型中定义的方法的结果对Eloquent ORM调用进行排序。我正在使用Laravel 5。
我想要一个posts
的列表,其中包括帖子author
,location
,comments
和counts
(这是views
的计数,upvotes
和downvotes
的帖子)。我希望列表按hotness
排序,这不是db中的字段(函数的结果)。
在\App\Counts
模型中,我们有一个名为hotness()
此方法对类似于reddit算法的算法执行计算[详见下文]
我有一个雄辩的ORM电话:
$posts = \App\Post::with('author')
->with('location.city')
->with('comments')
->with('counts')
->paginate(20);
\App\Counts
模型包含upvotes
,downvotes
,views
的字段,以及计算帖子热度时使用的一些其他变量。
我可以通过覆盖我的模型中的hotness
方法,将counts
模型添加到从toArray()
模型返回的数组中(在运行中),如下所示:< / p>
public function toArray()
{
$array = parent::toArray();
$array['hotness'] = $this->hotness();
return $array;
}
虽然这本身很有用,但我无法实现我的目标,即按每个帖子hotness
评分对ORM分页结果进行排序。
有没有什么方法可以实现这个没有让cron遍历所有帖子并每x分钟为每个帖子计算hotness
?
我希望能够只添加
->orderBy('hotness')
或
->orderBy('counts.hotness')
但我觉得这可能是不可能的。
关于如何解决这个问题的任何创意?
参考的热度算法
T
是帖子发布到网站上第一篇帖子的日期之间的秒数
x
是upvotes的数量减去downvotes的数量
y
-1 如果x < 0
, 0 如果x = 0
则 1 {{} {1}}
x > 0
是z
和1
答案 0 :(得分:0)
似乎我正在寻找的功能无法实现。
我最终将hotness
保留到counts
表并更新覆盖toArray()
方法中的值。
这允许我->orderBy('counts.hotness')
为了减轻开销,我使用一个15分钟后过期的缓存密钥,这样每次hotness
模型转换为数组时我都不会计算counts
。
我确定了15分钟,因为这样hotness
足够新鲜,可以用于本申请。