You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel查询构造器select查询如何返回包含点赞用户ID的数组?

Laravel 查询结果追加点赞用户ID数组解决方案

方案1:Eloquent 关联实现(推荐)

Laravel 官方推荐使用模型关联处理这类数据联动需求,可维护性更高,兼容不同数据库驱动。

  1. 首先定义Aktifitas模型及关联关系
// app/Models/Aktifitas.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class Aktifitas extends Model
{
    protected $table = 'aktifitas';

    // 定义与点赞表的一对多关联
    public function likes()
    {
        return $this->hasMany(Like::class, 'aktifitas_id');
    }
}
  1. 查询时预加载关联数据并格式化
// 查询逻辑
$posts = Aktifitas::query()
    ->withCount('likes as likes_count') // 统计点赞总数
    ->with('likes:id,aktifitas_id,user_id') // 预加载点赞数据,仅查询需要的字段减少IO
    ->latest()
    ->paginate(20);

// 格式化输出为要求的结构
$result = $posts->through(function ($post) {
    return [
        'id' => $post->id,
        'likes' => $post->likes_count,
        'user_like' => $post->likes->map(fn($like) => ['id' => $like->user_id])
    ];
});

// 直接return $result即可输出符合要求的JSON格式

方案2:DB 查询构造器原生实现

如果不想使用模型,可借助数据库原生JSON函数实现,以下示例兼容MySQL 5.7+/PostgreSQL:

$likes = DB::table('aktifitas')
    ->leftJoin('like', 'aktifitas.id', '=', 'like.aktifitas_id')
    ->select([
        'aktifitas.id',
        DB::raw('COUNT(like.aktifitas_id) as likes'),
        // 用JSON_AGG直接将点赞用户ID聚合为JSON数组
        DB::raw('JSON_ARRAYAGG(like.user_id) as user_like_ids')
    ])
    ->groupBy('aktifitas.id')
    ->latest()
    ->paginate(20);

// 格式化输出结构
$result = $likes->through(function ($item) {
    $userIds = json_decode($item->user_like_ids, true) ?: [];
    return [
        'id' => $item->id,
        'likes' => $item->likes,
        'user_like' => array_map(fn($id) => ['id' => $id], $userIds)
    ];
});

注意事项

  • 如果使用低于5.7版本的MySQL,可将JSON_ARRAYAGG替换为GROUP_CONCAT(like.user_id SEPARATOR ','),后续拆分字符串转换为数组即可
  • 若点赞表中存在空数据,可在JSON_ARRAYAGG中添加IFNULL判断避免返回null值

内容的提问来源于stack exchange,提问作者Robert tirta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 14:15:03