Prisma自关联一对多关系下类Tinder应用的匹配与候选用户查询问题
解决方案
第一步:优化模型字段命名(可选,建议调整)
你当前的模型反向关联字段命名可读性较差,容易混淆正向、反向关系,建议调整为如下结构,后续逻辑开发会更顺畅:
model User { id String @id username String @default("") age Int @default(0) bio String @default("") @db.VarChar(1000) // 我主动点赞的用户列表 likedUsers User[] @relation("UserLikes") // 主动给我点赞的用户列表 likedByUsers User[] @relation("UserLikes") // 我主动点踩的用户列表 dislikedUsers User[] @relation("UserDislikes") // 主动给我点踩的用户列表 dislikedByUsers User[] @relation("UserDislikes") }
调整后执行prisma migrate dev同步数据库结构即可。
第二步:查询匹配用户
匹配用户定义:你主动点赞过,且对方也主动给你点过赞的用户
const currentUserId = "当前登录用户的ID"; const matchUsers = await prisma.user.findMany({ where: { // 条件1:我给对方点过赞 likedByUsers: { some: { id: currentUserId } }, // 条件2:对方给我点过赞 likedUsers: { some: { id: currentUserId } } } });
第三步:查询候选用户
候选用户需要排除4类用户:你自己、匹配用户、你点踩过的用户、点踩过你的用户。可以先批量查询需要排除的用户ID,再直接过滤,逻辑清晰易维护:
const currentUserId = "当前登录用户的ID"; // 并行查询所有需要排除的用户ID,性能更高 const [myLikedIds, myDislikedIds, dislikedMeIds, matchIds] = await Promise.all([ // 我点赞过的用户ID prisma.user.findUnique({ where: { id: currentUserId } }).likedUsers({ select: { id: true } }), // 我点踩过的用户ID prisma.user.findUnique({ where: { id: currentUserId } }).dislikedUsers({ select: { id: true } }), // 给我点过踩的用户ID prisma.user.findUnique({ where: { id: currentUserId } }).dislikedByUsers({ select: { id: true } }), // 匹配用户ID prisma.user.findMany({ where: { likedByUsers: { some: { id: currentUserId } }, likedUsers: { some: { id: currentUserId } } }, select: { id: true } }) ]); // 合并所有需要排除的ID const excludeIds = [ currentUserId, ...myLikedIds.map(u => u.id), ...myDislikedIds.map(u => u.id), ...dislikedMeIds.map(u => u.id), ...matchIds.map(u => u.id) ]; // 过滤得到候选用户 const candidateUsers = await prisma.user.findMany({ where: { id: { notIn: excludeIds } } });
如果不调整模型字段名,只需要将上述代码中的字段名替换为你当前模型的对应字段即可正常运行。
内容的提问来源于stack exchange,提问作者Riccardo
相关产品推荐
相关产品推荐

