フィールドの選択
概要
デフォルトでは、クエリがレコード(カウントではなく)を返す場合、結果には以下が含まれます。
- モデルのすべてのスカラーフィールド(enumを含む)
- モデルに定義された**リレーションは含まれません**
例として、このスキーマを検討してください。
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
published Boolean @default(false)
title String
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
enum Role {
USER
ADMIN
}
`User` モデルへのクエリには、`id`、`email`、`name`、`role` フィールドが含まれます(これらはスカラーフィールドであるため)。しかし、`posts` フィールドは含まれません(これはリレーションフィールドであるため)。
const users = await prisma.user.findFirst()
{
id: 42,
name: "Sabelle",
email: "sabelle@prisma.io",
role: "ADMIN"
}
結果をカスタマイズし、異なるフィールドの組み合わせを返したい場合は、次のことができます。
- `select` を使用して特定のフィールドを返します。リレーションフィールドを選択することで、ネストされた `select` を使用することもできます。
- 結果から特定のフィールドを除外するには、`omit` を使用します。`omit` は `select` の「逆」と見なすことができます。
- 追加でリレーションを含めるには、`include` を使用します。
いずれの場合も、クエリ結果は静的に型付けされるため、データベースから実際にクエリしていないフィールドに誤ってアクセスすることはありません。
デフォルトの選択セットに依存するのではなく、必要なフィールドとリレーションのみを選択することで、レスポンスのサイズを削減し、クエリ速度を向上させることができます。
バージョン5.9.0以降では、`include` を使用したリレーションクエリを行う場合、またはリレーションフィールドで `select` を使用する場合に、`relationLoadStrategy` を指定して、データベースレベルの結合を使用するか、複数のクエリを実行してアプリケーションレベルでデータをマージするかを決定できます。この機能は現在プレビュー版です。こちらで詳細を確認できます。
スキーマの例
このページのすべての例は、以下のスキーマに基づいています。
model User {
id Int @id
name String?
email String @unique
password String
role Role @default(USER)
coinflips Boolean[]
posts Post[]
profile Profile?
}
model Post {
id Int @id
title String
published Boolean @default(true)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
model Profile {
id Int @id
biography String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
enum Role {
USER
ADMIN
}
デフォルトフィールドを返す
次のクエリはデフォルトフィールド(すべてのスカラーフィールド、リレーションなし)を返します。
const user = await prisma.user.findFirst()
{
id: 22,
name: "Alice",
email: "alice@prisma.io",
password: "mySecretPassword42"
role: "ADMIN",
coinflips: [true, false],
}
特定のフィールドを選択する
すべてのフィールドではなく、フィールドのサブセットを返すには `select` を使用します。次の例では、`email` と `name` フィールドのみを返します。
const user = await prisma.user.findFirst({
select: {
email: true,
name: true,
},
})
{
name: "Alice",
email: "alice@prisma.io",
}
リレーションフィールドを選択してネストされたオブジェクトを返す
リレーションフィールドで `select` を複数回ネストすることで、リレーションを返すこともできます。
次のクエリは、ネストされた `select` を使用して、各ユーザーの `name` と関連する各投稿の `title` を選択します。
const usersWithPostTitles = await prisma.user.findFirst({
select: {
name: true,
posts: {
select: { title: true },
},
},
})
{
"name":"Sabelle",
"posts":[
{ "title":"Getting started with Azure Functions" },
{ "title":"All about databases" }
]
}
次のクエリは、`include` 内で `select` を使用し、すべてのユーザーフィールドと各投稿の `title` フィールドを返します。
const usersWithPostTitles = await prisma.user.findFirst({
include: {
posts: {
select: { title: true },
},
},
})
{
id: 9
name: "Sabelle",
email: "sabelle@prisma.io",
password: "mySecretPassword42",
role: "USER",
coinflips: [],
posts:[
{ title:"Getting started with Azure Functions" },
{ title:"All about databases" }
]
}
クエリは任意に深くネストできます。次のクエリは以下を取得します。
- `Post` の `title`
- 関連する `User` の `name`
- 関連する `Profile` の `biography`
const postsWithAuthorsAndProfiles = await prisma.post.findFirst({
select: {
title: true,
author: {
select: {
name: true,
profile: {
select: { biography: true }
}
},
},
},
})
{
id: 9
title:"All about databases",
author: {
name: "Sabelle",.
profile: {
biography: "I like turtles"
}
}
}
リレーションを深くネストする場合は注意が必要です。基盤となるデータベースクエリが多くの異なるテーブルにアクセスする必要があるため、遅くなる可能性があります。クエリが常に最適な速度を持つようにするには、Prisma Accelerate でキャッシュレイヤーを追加するか、Prisma Optimize を使用してクエリのインサイトとパフォーマンス最適化の推奨事項を取得することを検討してください。
リレーションのクエリに関する詳細については、以下のドキュメントを参照してください。
特定のフィールドを除外する
モデルのほとんどのフィールドを返したいが、ごく一部のフィールドを除外したい場合があります。よくある例としては、`User` をクエリする際にセキュリティ上の理由から `password` フィールドを除外したい場合などです。
これらの場合、`select` の対義語と見なせる `omit` を使用できます。
const users = await prisma.user.findFirst({
omit: {
password: true
}
})
{
id: 9
name: "Sabelle",
email: "sabelle@prisma.io",
profileViews: 90,
role: "USER",
coinflips: [],
}
返されたオブジェクトに `password` フィールドが含まれていないことに注目してください。
リレーションのカウント
3.0.1以降では、フィールドと並行してリレーションのカウントを含めるか、選択することができます。たとえば、ユーザーの投稿数などです。