我正在尝试按视频观看次数对序列进行排序。
关系: 序列号与序列号具有hasMany关系。 系列与剧集有hasMany关系。 情节与视频具有hasOne关系。 该视频与观看次数具有hasMany关系。
<?php
//sort method:
public function mostPopular()
{
$serials = Serial::with(['series.episodes.video' => function ($query) {
$query->withCount(['videoViews' => function($query) {
}])->orderBy('video_views_count', 'desc');
}])->get();
return $serials;
}
//Serial model:
public function series()
{
return $this->hasMany(Series::class);
}
//Series model:
public function episodes()
{
return $this->hasMany(Episode::class);
}
public function serial()
{
return $this->belongsTo(Serial::class);
}
//Episode model:
public function video()
{
return $this->hasOne(Video::class);
}
public function series()
{
return $this->belongsTo(Series::class);
}
//Video model:
public function videoViews()
{
return $this->hasMany(VideoView::class);
}
public function episode()
{
return $this->belongsTo(Episode::class);
}
?>
我期望按视频视图(series.episodes.video.videoViews)排序的序列,但是实际输出未排序。
Laravel 5.8 PHP 7
答案 0 :(得分:0)
因为“ With”查询作为单独的查询(而不是以前建议的子查询)运行,因此将推算的fuax列从一个查询暴露给另一个查询变得非常棘手。我确定API文档中有未记录的解决方案,但我从未遇到过。您可以尝试将with和withCount放入orderBy:
Serial::orderBy(function($query) { some combo of with and withCount })
但这也会变得棘手。由于这两种方法都会多次访问数据库,因此您自己执行分离并同时保持理智与执行性能相同。第一个查询使用左连接,原始分组依据和原始选择,因为我不希望laravel将with查询作为单独的查询运行(首先是问题)。
$seriesWithViewCounts = VideoView::leftJoin('episodes', 'episodes.id', '=', 'video_views.episode_id')
->groupBy(DB::raw('episodes.series_id'))
->selectRaw("episodes.series_id, count(video_views.id) as views")
->get();
$series = Series::findMany($seriesWithViewCounts->pluck('series_id'));
foreach($series as $s) {
$s->view_count = $seriesWithViewCounts->first(function($value, $key) use ($s) {
return $value->series_id = $s->id
})->video_views_count;
});
$sortedSeries = $series->sortBy('video_views_count');
这将忽略所有对所有情节都无视的剧集,因此您可能要抓住这些情节并将其追加到末尾。不是我对“大众”的定义。
我希望看到一种更雄辩的方法来处理此问题,但这可以完成工作。
答案 1 :(得分:0)
实际上这是一个愚蠢的选择,但是我已经知道,在没有解决方法的情况下,实际上可以对集合进行多个-> sortBy排序。只是您需要颠倒它们的顺序。因此,要对带有专辑标题的艺术家目录进行排序,这就是解决方案...
而不是:
$collection->sortBy('artist')->sortBy('title');
执行此操作:
$collection->sortBy('title')->sortBy('artist');