Objection.js中如何使.modifyGraph返回指定别名的布尔值
Objection.js 关联查询自定义别名字段返回布尔值实现方法
你当前编写的可正常运行的基础查询代码如下:
UserReaction.query().where({ target_id: userId, type, }) .withGraphFetched('[user.[user_data, reactions]]') .modifyGraph('user.reactions', builder => { builder.where('user_id', '=', userId) })
当前问题:经modifyGraph过滤的user.reactions字段默认返回匹配的反应记录对象数组,需要为该逻辑设置独立别名、最终返回布尔类型的判断结果。
核心说明
不要尝试直接在modifyGraph回调里把关联的reactions数组替换成布尔值:Objection的图加载逻辑(withGraphFetched/withGraphJoined)会严格按照模型关联定义返回对应结构的关联模型集合,不支持直接在关联修改回调里把集合类型替换为单值字段。以下两种方案都可以实现需求:
方案1:查询阶段直接生成布尔别名(推荐,性能更好)
移除原有图加载里的reactions关联预加载,在user关联的查询回调里新增自定义聚合字段,直接在数据库查询层返回你需要的布尔值,字段名可完全自定义(例如下方示例用has_reacted作为别名):
UserReaction.query() .where({ target_id: userId, type, }) .withGraphFetched('[user.[user_data]]') .modifyGraph('user', builder => { builder.select( 'users.*', // 子查询统计对应用户的匹配反应记录数 UserReaction.query() .whereRaw('user_reactions.user_id = users.id') .where('target_id', userId) .where('type', type) .count(1) .castTo('boolean') // 直接把统计结果转为布尔值 .as('has_reacted') // 自定义字段别名 ) })
该方案没有额外的内存遍历开销,查询返回的结果直接带目标布尔字段,不会返回多余的反应记录数组。
方案2:查询后做结果格式转换(改动最小)
如果不想调整原有查询的图加载结构,就在查询拿到结果后遍历做字段转换,把原reactions数组的长度判断转为布尔值,同时重命名为目标别名、移除原数组字段即可:
const reactionList = await UserReaction.query().where({ target_id: userId, type, }) .withGraphFetched('[user.[user_data, reactions]]') .modifyGraph('user.reactions', builder => { builder.where('user_id', '=', userId) }); // 格式转换 const formattedList = reactionList.map(item => { const { reactions, ...restUserData } = item.user; return { ...item, user: { ...restUserData, has_reacted: reactions.length > 0 // 有匹配记录即为true,否则为false } } })
该方案只需要在原有代码基础上加几行转换逻辑,适合查询逻辑已经稳定、不想调整SQL生成规则的场景。
内容的提问来源于stack exchange,提问作者PGT
相关产品推荐
相关产品推荐

