我正在使用 Lumen 创建一个 REST API。我有图片
和picture_likes
表格和模型,我正在尝试获取最喜欢的图片。
我的图片表
看起来像..
photo_id | path | owner_id | created_at
我的PictureLikes 表
看起来像...
id | user_id who liked
0 1
1 2
2 4
3 3
4 5
etc...
我的第一个问题是如何获得最喜欢的图片。我认为我可以通过对相似的 photo_id 进行分组并按数量对它们进行排序来获得最喜欢的照片。但是,我不知道如何按计数排序。
然后,我可以更进一步,获取过去 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 天的照片?
最佳答案
在开始之前,我发现您的视频表名称称为图片有点奇怪。哈哈,另外,您将模型命名为 Picture
和 Photo
,因此在图片、视频和照片之间,您实际命名的内容有点令人困惑。
无论如何,为了达到你想要的效果,你可以使用 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();
这将连接 pictures
和 picture_likes
表。它将按 photo_id
分组。它选择 pictures
表中的所有列,并计算 picture_likes
表中 photo_id
的实例。它的别名计为 total_likes
。这样,您就可以按 total_likes
进行订购。
有了这个,你可以循环它并做任何你想做的事情。例如,这将回显 photo_id
和 total_likes
。
foreach ($pictures as $picture)
{
echo $picture->photo_id . ': ' . $picture->total_likes . '<br>';
}
现在,获取过去 7 天内最受点赞的照片存在问题,因为您的 picture_likes
表没有指示图片何时被点赞的 created_at
列。相反,您只能获取过去 7 天内创建的最受欢迎的照片。两者的含义根本不同。第一个对于当前的表结构来说是不可能的。第二个是可行的。只需向上面的示例添加一个 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获取当前日期/时间并减去一周。
关于php - 查询构建器按(groupBy 行数)排序并获取 X 天前之后的条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34056960/