根据相关模型中方法的结果对Eloquent ORM结果集进行排序

时间:2015-02-23 16:29:16

标签: php algorithm laravel orm eloquent

我正在尝试根据相关模型中定义的方法的结果对Eloquent ORM调用进行排序。我正在使用Laravel 5。

我想要一个posts的列表,其中包括帖子authorlocationcommentscounts(这是views的计数,upvotesdownvotes的帖子)。我希望列表按hotness排序,这不是db中的字段(函数的结果)。

\App\Counts模型中,我们有一个名为hotness()

的方法

此方法对类似于reddit算法的算法执行计算[详见下文]

我有一个雄辩的ORM电话:

$posts = \App\Post::with('author')
  ->with('location.city')
  ->with('comments')
  ->with('counts')
  ->paginate(20);

\App\Counts模型包含upvotesdownvotesviews的字段,以及计算帖子热度时使用的一些其他变量。

我可以通过覆盖我的模型中的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')

但我觉得这可能是不可能的。

关于如何解决这个问题的任何创意?


参考的热度算法

enter image description here

T是帖子发布到网站上第一篇帖子的日期之间的秒数

x是upvotes的数量减去downvotes的数量

y -1 如果x < 0 0 如果x = 0 1 {{} {1}}

x > 0z和1

的绝对值

1 个答案:

答案 0 :(得分:0)

似乎我正在寻找的功能无法实现。

我最终将hotness保留到counts表并更新覆盖toArray()方法中的值。

这允许我->orderBy('counts.hotness')

为了减轻开销,我使用一个15分钟后过期的缓存密钥,这样每次hotness模型转换为数组时我都不会计算counts

我确定了15分钟,因为这样hotness足够新鲜,可以用于本申请。