Eager loading
QueryBuilderのeagerメソッドを使用することで、Eager loadingを実行できます。
Eager loadingを使用することで、N+1問題を解決できます。
使用例
単一のリレーションを取得する
eagerメソッドの引数に、リレーション名を指定する。
(ModelのrelationMappingsプロパティのキーを指定する)
const projects = await Project.query()
.eager('tasks');
console.log(
projects.every(
project => project.tasks.every(task => task instanceof Task)
)
); // true
デフォルトでは、以下のようなSQLが実行される。
select "projects".* from "projects";
select "tasks".* from "tasks" where "tasks"."projectId" in (1, 33, 34);
2つ以上のリレーションを同時に取得する
[]
で囲み、カンマ区切りで複数のリレーション名を指定する。
const projects = await Project.query()
.eager('[tasks, members]');
console.log(
projects.every(
project => project.tasks.every(task => task instanceof Task)
)
); // true
console.log(
projects.every(
project => project.members.every(member => member instanceof User)
)
); // true
デフォルトでは、以下のようなSQLが実行される。
select "projects".* from "projects";
select "tasks".* from "tasks" where "tasks"."projectId" in (1, 33, 34);
select "users".*, "projectMembers"."projectId" as "objectiontmpjoin0" from "users" inner join "projectMembers" as "projectMembers" on "users"."id" = "projectMembers"."userId" where "projectMembers"."projectId" in (1, 33, 34);
入れ子になったリレーションを取得する
eagerメソッドの引数として、各リレーション名をドットでつないだ文字列を渡す。
const projects = await Project.query()
.eager('members.tasks');
console.log(
projects.every(
project => project.members.every(
member => member.tasks.every(task => task instanceof Task)
)
)
); // true
デフォルトでは、以下のようなSQLが実行される
select "projects".* from "projects";
select "users".*, "projectMembers"."projectId" as "objectiontmpjoin0" from "users" inner join "projectMembers" as "projectMembers" on "users"."id" = "projectMembers"."userId" where "projectMembers"."projectId" in (1, 33, 34);
select "tasks".* from "tasks" where "tasks"."assignedTo" in (1, 2, 23);
特定のリレーションに対してフィルターを適用する
modifyEagerメソッドを使用する。
const projects = await Project.query()
.eager('members.tasks')
.modifyEager('members.tasks', builder => {
// projects[].members[].tasksを、締め切りの昇順で並び替える
builder.orderBy('deadline', 'asc');
});
デフォルトでは、以下のようなSQLが実行される。
select "projects".* from "projects"
select "users".*, "projectMembers"."projectId" as "objectiontmpjoin0" from "users" inner join "projectMembers" as "projectMembers" on "users"."id" = "projectMembers"."userId" where "projectMembers"."projectId" in (1, 33, 34);
select "tasks".* from "tasks" where "tasks"."assignedTo" in (1, 2, 23) order by "deadline" asc;
参考