Laravel如何对同一列使用两次where条件查询指定用户关联会话
Laravel 多用户匹配关联会话实现方案
需求说明
开发无宿主属性的聊天应用时,需要根据传入的多个用户ID,精准定位到这些用户共同所属的会话。例如USER_1与USER_2同属于CONVERSATION_1时,传入两个用户ID即可筛选出CONVERSATION_1。
现有结构
- 会话表
conversations
id product_id
- 会话用户关联表
conversation_users
id conversation_id user_id
原有写法问题
原代码中$q->where("user_id", $user->id)->where("user_id", $admin->id)的写法,要求单条关联记录的user_id同时等于两个不同的数值,逻辑上永远无法返回匹配结果,不符合需求。
正确实现代码
核心思路是先匹配目标范围内的用户关联记录,再通过分组聚合校验关联的用户数恰好和传入的用户总数一致,既保证所有目标用户都在会话内,也排除包含额外无关用户的会话。
class ConversationService { /** * 根据用户ID列表查询共同所属会话 * @param array $userIds 目标用户ID数组 * @return \App\Models\Conversation|null */ public static function findByUserIds(array $userIds) { $targetUserCount = count($userIds); return Conversation::whereHas('users', function($query) use ($userIds, $targetUserCount) { $query->whereIn('user_id', $userIds) ->groupBy('conversation_id') ->havingRaw('COUNT(DISTINCT user_id) = ?', [$targetUserCount]); })->first(); } public static function first(User $user){ $admin = getAdmin(); return self::findByUserIds([$user->id, $admin->id]); } }
逻辑拆解
whereIn('user_id', $userIds):先过滤出关联用户属于目标用户列表的中间表记录groupBy('conversation_id'):按会话ID对关联记录做分组聚合havingRaw('COUNT(DISTINCT user_id) = ?', [$targetUserCount]):校验每个会话分组下匹配到的去重用户数,和传入的目标用户总数完全相等,避免漏匹配或者匹配到包含多余用户的会话
建议给
conversation_users表的conversation_id和user_id字段添加联合唯一索引,避免重复关联数据,提升查询效率。
内容的提问来源于stack exchange,提问作者mg tint
相关产品推荐
相关产品推荐

