如何在Laravel中查询两个用户之间的最新一条聊天消息
实现方案
原有查询会返回当前用户作为收发件人的所有历史消息,可根据实际需求选择对应写法:
场景1:所有相关消息按时间倒序排列
如果只需要把所有和当前用户有关的消息按最新发布顺序展示,直接补充排序条件即可:
$userId = Auth::id(); $messages = Messages::where('to', $userId) ->orWhere('from', $userId) ->orderBy('created_at', 'desc') ->get();
场景2:获取每个会话的最新一条消息(会话列表场景)
如果是要做类似微信的会话列表,展示和每个联系人的最新对话,先确认已经引入DB门面:
use Illuminate\Support\Facades\DB;
再使用分组查询实现:
$userId = Auth::id(); // 子查询获取每个会话的最新消息ID $latestMessageIds = Messages::selectRaw('MAX(id) as message_id') ->where(function ($query) use ($userId) { $query->where('to', $userId) ->orWhere('from', $userId); }) // 双向收发的消息归为同一个会话分组 ->groupBy(DB::raw('LEAST(`from`, `to`), GREATEST(`from`, `to`)')) ->pluck('message_id'); // 查询完整消息内容,最新会话靠前 $latestMessages = Messages::whereIn('id', $latestMessageIds) ->orderBy('created_at', 'desc') ->get();
逻辑说明
- 用
LEAST和GREATEST函数组合收发双方ID,避免把A发给B、B发给A的消息划分为两个会话 - 每个会话分组取最大自增ID对应的记录即为该会话最新消息,若表ID非自增,可替换为按
MAX(created_at)匹配对应消息ID - 需要分页时将最终查询的
get()方法替换为paginate(每页条数)即可
内容的提问来源于stack exchange,提问作者Robin Singh
相关产品推荐
相关产品推荐

