Laravel多对多中间表查询:筛选指定分类推荐视频并去空值
解决方案
直接通过关联查询或JOIN语句一次性获取符合条件的视频,避免循环查询带来的空元素和性能问题,以下是几种可行方案:
方案1:利用分类模型的多对多关联(推荐)
如果你的Category模型已经定义了与Video的多对多关联:
// Category模型中的关联定义 public function videos() { return $this->belongsToMany(Video::class, 'video_category'); }
直接通过分类模型查询指定分类下featured=1的视频:
$featuredVideos = Category::findOrFail($category_id) ->videos() ->where('featured', 1) ->get();
方案2:利用CategoryVideo模型的videofeatured关联
如果CategoryVideo模型的videofeatured关联已经过滤了featured=1的视频:
// CategoryVideo模型中的关联定义 public function videofeatured() { return $this->belongsTo(Video::class, 'video_id')->where('featured', 1); }
可以通过预加载关联并过滤空值来得到有效视频:
$featuredVideos = CategoryVideo::where('category_id', $category_id) ->with('videofeatured') ->get() ->pluck('videofeatured') ->filter() // 自动剔除null元素 ->values(); // 重置数组索引,避免空索引
方案3:直接使用JOIN查询
如果不需要依赖模型关联,直接通过原生JOIN语句查询:
$featuredVideos = Video::join('video_category', 'videos.id', '=', 'video_category.video_id') ->where('video_category.category_id', $category_id) ->where('videos.featured', 1) ->select('videos.*') ->get();
原代码问题说明
你之前的方法先获取视频ID再循环查询,会出现空元素的原因是:
- 部分
video_id对应的视频可能已被删除,查询返回null - 部分视频的
featured值不为1,查询结果为空
这些空值被加入数组后就会产生空索引。上面的方案通过一次性查询直接筛选出符合条件的视频,从根源避免了空元素的出现。
如果需要将结果转为普通数组而非Eloquent集合,只需在最后调用->toArray()即可;如果只需要视频ID数组,可使用->pluck('id')->toArray()。
内容的提问来源于stack exchange,提问作者Ondraasek
相关产品推荐
相关产品推荐

