GraphQL解析器中关联Cruises与Rooms集合的问题
解决Cruises与Rooms集合的GraphQL关联问题
我来帮你搞定这个关联问题!核心问题在于你之前的Resolver没有正确利用当前Cruise对象的roomTypes字段来过滤房间,反而误用了cruiseID查询所有关联房间,导致返回结果不符合预期。下面是具体的解决思路和代码示例:
问题根源拆解
你的Cruises集合里的roomTypes是指定该游轮关联的roomID子集,而Rooms集合里的capacity信息是对应每个游轮的。之前用cruiseID查询Rooms会返回所有和该游轮有关的房间,但你需要的是Cruise对象里明确列出的那些roomID对应的房间,所以必须以roomTypes数组作为核心过滤条件。
正确的Resolver写法
示例1:使用MongoDB原生驱动
假设你的Context里已经注入了数据库连接,Resolver可以这么写:
const resolvers = { Cruise: { roomTypes: async (root, _, context) => { // 从当前Cruise对象(root)中获取指定的roomID列表 const targetRoomIds = root.roomTypes; // 空数组直接返回空结果 if (!targetRoomIds || targetRoomIds.length === 0) { return []; } // 查询Rooms集合,只返回roomID在targetRoomIds中的文档 // 可选:加上cruiseID过滤,确保房间确实属于当前游轮(双重验证) return context.db.collection('Rooms').find({ roomID: { $in: targetRoomIds }, cruiseID: root.cruiseID }).toArray(); } } };
示例2:使用Prisma ORM
如果用Prisma作为数据库中间层,写法会更简洁:
const resolvers = { Cruise: { roomTypes: async (root, _, context) => { return context.prisma.room.findMany({ where: { roomID: { in: root.roomTypes }, cruiseID: root.cruiseID } }); } } };
关键注意事项
- 确保root参数正确传递:Resolver的第一个参数默认就是当前的Cruise对象,你需要确认Schema里的
roomTypes字段关联配置正确,能让GraphQL正确传递这个root对象。 - 类型匹配检查:确认
roomID的类型(字符串/数字)在两个集合中一致,避免因为类型不匹配导致$in查询无结果。 - 双重验证可选但推荐:加上
cruiseID过滤可以防止因为数据脏读(比如某个roomID被错误关联到多个游轮)导致返回错误的房间数据。
这样修改后,你的GraphQL查询就能返回Cruise中roomTypes字段指定的那些房间,而不是所有关联该游轮的房间了。
内容的提问来源于stack exchange,提问作者Przemek
相关产品推荐
相关产品推荐

