[英]Ordering an Eloquent ORM resultset based on the result of a method in a related model
I'm trying to sort an Eloquent ORM call based on the result of a method defined in a related model. 我正在尝试根据相关模型中定义的方法的结果对Eloquent ORM调用进行排序。 I'm using Laravel 5. 我正在使用Laravel 5。
I want a list of posts
including the posts author
, location
, comments
and counts
(which is a count of views
, upvotes
and downvotes
for a post). 我想要一个posts
列表,包括帖子author
, location
, comments
和counts
(这是一个帖子的views
, upvotes
和downvotes
的计数)。 I want the list sorted by hotness
, which is not a field in the db (the result of a function). 我希望列表按hotness
排序,这不是db中的字段(函数的结果)。
In the \\App\\Counts
model we have a method called hotness()
在\\App\\Counts
模型中,我们有一个名为hotness()
的方法
This method performs a calculation on an algorithm similar to the reddit algorithm [see below for details] 此方法对类似于reddit算法的算法执行计算[详见下文]
I have a an Eloquent ORM call: 我有一个雄辩的ORM电话:
$posts = \App\Post::with('author')
->with('location.city')
->with('comments')
->with('counts')
->paginate(20);
The \\App\\Counts
model contains fields for upvotes
, downvotes
, views
, and a few other variables that are used when calculating the hotness of the post. \\App\\Counts
模型包含upvotes
, downvotes
, views
以及计算帖子upvotes
时使用的一些其他变量的字段。
I can add the hotness
value to the array that comes back from the counts
model when paginating (on the fly) by overriding the toArray()
method in my model like this: 我可以通过在我的模型中覆盖toArray()
方法,在分页(动态)时将hotness
值添加到从counts
模型返回的数组中,如下所示:
public function toArray()
{
$array = parent::toArray();
$array['hotness'] = $this->hotness();
return $array;
}
While this is useful in its own right, I can't achieve my objective, which is to sort the ORM paginated result by each posts hotness
rating. 虽然这本身就很有用,但我无法实现我的目标,即按每个帖子hotness
等级对ORM分页结果进行排序。
Is there any way I can achieve this without having a cron go through all the posts and calculate the hotness
for each post every x minutes? 有没有什么方法可以实现这一目标, 而不是让cron通过所有帖子并计算每x分钟每个帖子的hotness
?
I would ideally like to be able to just add 理想情况下,我希望能够添加
->orderBy('hotness')
or 要么
->orderBy('counts.hotness')
but I have a feeling this might not be possible. 但我有一种感觉,这可能是不可能的。
Any creative ideas around how to solve this? 关于如何解决这个问题的任何创意?
Hotness Algorithm for reference 热度算法供参考
T
is the time in seconds between when the post was made an the date of the first post on the website T
是帖子发布到网站上第一篇帖子的日期之间的秒数
x
is the number of upvotes minus the number of downvotes x
是upvotes的数量减去downvotes的数量
y
is -1 if x < 0
, 0 if x = 0
and 1 if x > 0
y
是-1,如果x < 0
,0,如果x = 0
和1,如果x > 0
z
is the absolute value of x
and 1 z
是x
和1的绝对值
It seems that the functionality I'm looking for is not achievable. 似乎我正在寻找的功能是不可实现的。
I ended up persisting hotness
to the counts
table and update the value in the overriding toArray()
method. 我最终坚持hotness
到counts
表并更新覆盖toArray()
方法中的值。
This allows me to ->orderBy('counts.hotness')
这允许我->orderBy('counts.hotness')
In order to mitigate overhead I use a cache key that expires after 15 minutes so that I'm not calculating the hotness
each time the counts
model is converted to an array. 为了减轻开销,我使用一个15分钟后过期的缓存密钥,这样每次将counts
模型转换为数组时我都不会计算hotness
。
I settled on 15 minutes as this allows the hotness
to be fresh enough for the purposes of this application. 我坚持了15分钟,因为这样可以使hotness
足够新鲜,以满足本申请的需要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.