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

Laravel中如何查询仅匹配指定收件人集合的聊天消息

实现方案

要实现完全匹配指定用户集合的消息查询,需要同时满足两个条件:

  1. 消息的收件人包含所有指定的用户ID
  2. 消息没有指定用户ID之外的其他收件人

Laravel 7+ 可以通过组合whereHas和whereDoesntHave实现,代码如下:

$queryUserIds = [2,3];
$targetUserCount = count($queryUserIds);

return Message::whereHas('recipients', function ($query) use ($queryUserIds) {
    $query->whereIn('userId', $queryUserIds);
}, '=', $targetUserCount) // 要求正好匹配到所有目标用户,没有缺漏
->whereDoesntHave('recipients', function ($query) use ($queryUserIds) {
    $query->whereNotIn('userId', $queryUserIds);
}) // 排除包含目标用户之外的收件人的消息,没有多余用户
->orderBy('id', 'DESC')
->get();

逻辑说明

你之前的whereIn写法只判断消息存在至少一个匹配的收件人,没有限制总数量和额外用户。上述代码的两个条件组合后,刚好实现完全匹配的效果,你举的示例中查询[2,3]时,会返回空结果,完全符合预期。

如果你的业务数据量较大,可以使用join+聚合的写法优化性能,避免两次子查询:

$queryUserIds = [2,3];
$targetUserCount = count($queryUserIds);

return Message::join('recipients', 'messages.id', '=', 'recipients.messageId')
    ->groupBy('messages.id')
    ->havingRaw('COUNT(DISTINCT recipients.userId) = ?', [$targetUserCount])
    ->havingRaw('SUM(CASE WHEN recipients.userId NOT IN (?) THEN 1 ELSE 0 END) = 0', [implode(',', $queryUserIds)])
    ->orderBy('messages.id', 'DESC')
    ->get(['messages.*']);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:15:03