查询构建器以排序(groupBy 行数)并在 X 天前获取条目

Query builder to orderBy (count of groupBy'ed rows) & get entries after X day ago

我正在用 Lumen 休息 api。我有 pictures & picture_likes 表格和模型,我正在尝试获取最喜欢的图片。

我的Pictures table看起来像..

  photo_id | path | owner_id | created_at

我的PictureLikes table看起来像...

  id  | user_id who liked 
   0          1
   1          2
   2          4
   3          3
   4          5
   etc...       

我的第一个问题是如何获得最喜欢的图片。我想我可以通过将相似的 photo_ids 分组并按数量排序来获得最喜欢的照片。但是,我不知道如何按计数排序。

然后,我可以走得更远,获得最近 7 天最喜欢的照片(相对于今天移动)。我的第二个问题是,如何过滤最喜欢的图片,只显示最近X天最喜欢的照片?

更新: 我的第一个问题成功了:

  $photos = Photo::all(); // returns all photos
  $photoLikes = PhotoLikes::all(); // returns all photoLikes

  $photoLikes = PhotoLike::select('photo_id', \DB::raw('count(*) as total'))
                                    ->groupBy('photo_id')
                                    ->orderBy('total', 'desc')
                                    ->get()->toArray();

结果看起来:

array:10 [
  0 => array:2 [
    "photo_id" => 1
    "total" => 5
  ]
  1 => array:2 [
    "photo_id" => 10
    "total" => 5
  ]
  ..etc

但是,如何使用此变量获取最近 X 天的照片?

开始之前,我发现您的 table 视频名称被称为图片有点奇怪。哈哈,另外,你把你的模型命名为 PicturePhoto 所以在图片、视频和照片之间,你实际命名的东西有点混乱。

总之,为了达到你想要的效果,你可以使用joins。例如:

$pictures = Picture::selectRaw('pictures.*, count(picture_likes.photo_id) as total_likes')
    ->join('picture_likes', 'picture_likes.photo_id', '=', 'pictures.photo_id')
    ->groupBy('pictures.photo_id')
    ->orderBy('total_likes', 'DESC')
    ->get();

这将加入 picturespicture_likes table。它将按 photo_id 分组。它选择 pictures table 中的所有列,并计算 picture_likes table 中 photo_id 的实例。它别名为 total_likes。这样,您可以按 total_likes.

订购

有了这个,你可以遍历它,做任何你想做的事。例如,这将回显 photo_idtotal_likes.

foreach ($pictures as $picture)
{
    echo $picture->photo_id . ': ' . $picture->total_likes . '<br>';
}

现在,获取过去 7 天内点赞次数最多的照片时出现问题,因为您的 picture_likes table 没有 created_at 列指示图片何时被点赞。相反,您只能获取过去 7 天内创建的最受赞的照片。两者的意思根本不同。当前的 table 结构不可能实现第一个。第二个是可行的。只需在上面的示例中添加一个 whereDate 方法,如下所示:

$pictures = Picture::selectRaw('pictures.*, count(picture_likes.photo_id) as total_likes')
    ->whereDate('pictures.created_at', '>=', Carbon::now()->subWeek())
    ->leftJoin('picture_likes', 'picture_likes.photo_id', '=', 'pictures.photo_id')
    ->groupBy('pictures.photo_id')
    ->orderBy('total_likes', 'DESC')
    ->get();

再一次,这将获得过去 7 天内创建的最喜欢的图片。我用Carbon得到当前的date/time减去一周