检查以删除过期的帖子拉拉维尔



我有一个帖子模型,它将在一段时间内由用户提升,现在我有一个 crone 工作,每 15 分钟午餐一次,以运行一个特殊的脚本以查看帖子是提升还是完成。 但问题是每次它循环所有帖子并且需要一定的时间,我想知道是否有任何替代和更好的方法来做到这一点?这是我下面的代码:

$boosted = POST::whereIn('status_id', [4, 5, 6])->where('boosted',1)->get();
foreach ($boosted as $index => $item) {
if ($item->boosted_until < Carbon::now()) {
$wish = Wish::find($item->id);
$wish->boosted = 0;
$wish->save();
}

根据我对你的问题的评论,你可以有一些类似但准确的东西:

如果将其设置为关系


Wish::whereHas('posts', function($query){ 
$query->where('boosted_until', '<', Carbon::now());
})->where('boosted', 1)->update(['boosted' => 0]);

我认为问题是。这是可能导致执行时间错误的大量数据。我建议您在 laravel 中使用队列 https://laravel.com/docs/6.x/queues 在后台运行它。您也可以将它们切成碎片。例如,您将要循环 100k 行数据。最好将它们分成几部分,以便队列作业顺利进行。

值得庆幸的是,我们可以使用预先加载将此操作减少到仅 2 个查询。查询时,您可以使用with方法指定应预先加载哪些关系:

我假设您已经hasMany帖子和愿望模型之间的关系

// AppPost Model
public function wishes() {
return $this->hasMany('AppWish');
}

// Controller
//...
$boosted = POST::with('wishes')->whereIn('status_id', [4, 5, 6])->where('boosted',1)->get();
$wishesIDsToUpdate = [];    
foreach ($boosted as $index => $item) {
if ($item->boosted_until < Carbon::now()) {
foreach($item->wishes as $wish) {
$wishesIDsToUpdate[] = $wish->id;
}
}                  
}
if(!empty($wishesIDsToUpdate)) {
Wish::whereIn('id', $wishesIDsToUpdate)->update(['boosted' => 0]);
}

最新更新