如何在Kysely中扁平化多对多关联的嵌套查询结果?
解决Kysely查询中用户团队嵌套层级冗余的问题
你的查询之所以出现冗余的teams层级,是因为嵌套了两层jsonArrayFrom——内层在UserToTeam查询里又包裹了一次Team的数组查询,导致每条关联记录都生成一个带teams字段的对象,外层再把这些对象收集起来,就形成了嵌套结构。
直接修改withTeams函数,通过关联查询直接获取Team对象,外层只用一次jsonArrayFrom收集即可:
const result = await db .selectFrom("User") .select(["id", "name"]) .select((eb) => [withTeams(eb)]) .execute(); function withTeams(eb: ExpressionBuilder<DB, "User">) { return jsonArrayFrom( eb .selectFrom("UserToTeam") // 直接关联UserToTeam和Team表 .innerJoin("Team", "Team.id", "UserToTeam.teamId") // 选择Team的字段 .select(["Team.id", "Team.name"]) .whereRef("UserToTeam.userId", "=", "User.id"), ).as("teams"); }
修改后返回的结果会是扁平化的结构:
[ { "id": "1fd0a910-8871-41b2-9a42-303e82a47713", "name": "Jane Doe", "teams": [] }, { "id": "c7d86c73-091f-44c1-b89a-6f6cb6ba9ed0", "name": "John Doe", "teams": [ { "id": "07dc9a2c-52c1-4d1d-8c07-ba21dc98f733", "name": "Team 1" } ] } ]
核心逻辑是:通过innerJoin直接关联关联表UserToTeam和目标表Team,一次性拿到用户对应的所有Team数据,再用jsonArrayFrom把这些Team对象直接打包成数组,避免了多余的嵌套层级。
内容的提问来源于stack exchange,提问作者Adam A
相关产品推荐
相关产品推荐

