LoginSignup
1
2

More than 5 years have passed since last update.

Node.js向けORM Objection.jsを使ってみた(7) - Eager loading

Last updated at Posted at 2018-08-19

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;

参考

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2