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

Ordering an Eloquent ORM resultset based on the result of a method in a related model

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

我想要一个 posts 的列表,包括 posts authorlocationcommentscounts(这是一个viewsupvotesdownvotes 的计数 post)。我希望列表按 hotness 排序,这不是数据库中的字段(函数的结果)。

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

的方法

该方法对类似reddit算法的算法进行计算[详见下文]

我有一个 Eloquent ORM 调用:

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

\App\Counts 模型包含 upvotesdownvotesviews 的字段,以及在计算 [=97] 的热度时使用的一些其他变量=].

我可以将 hotness 值添加到分页时(动态)从 counts 模型返回的数组,方法是像这样重写我模型中的 toArray() 方法:

public function toArray()
{
    $array = parent::toArray();
    $array['hotness'] = $this->hotness();
    return $array;
}

虽然这本身很有用,但我无法实现我的 objective,即按每个 post 的 hotness 评级对 ORM 分页结果进行排序。

有什么方法可以实现这个 而无需 让 cron 遍历所有 post 并为每个 [=97] 计算​​ hotness =] 每 x 分钟?

理想情况下,我希望能够添加

->orderBy('hotness')

->orderBy('counts.hotness')

但我感觉这不可能。

关于如何解决这个问题有什么创意吗?


热度算法供参考

T 是 post 与网站上第一个 post 日期之间的时间间隔(以秒为单位)

x是赞成数减去反对数

y-1 如果 x < 00 如果 x = 01 如果 x > 0

zx和1

的绝对值

看来我要找的功能无法实现。

我最终坚持 hotnesscounts table 并更新覆盖 toArray() 方法中的值。

这让我可以 ->orderBy('counts.hotness')

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

我选择了 15 分钟,因为这样 hotness 就此应用而言足够新鲜。