選擇欄位
概述
預設情況下,當查詢返回記錄(而非計數)時,結果包含
- 模型的所有標量欄位(包括列舉)
- 模型上未定義的關係
例如,考慮此 schema
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 來決定是使用資料庫級別的連線還是執行多個查詢並在應用程式級別合併資料。此功能目前處於預覽階段,你可以在此處瞭解更多資訊。
示例 Schema
本頁所有後續示例均基於以下 schema
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 欄位。
在這些情況下,你可以使用 omit,這可以看作是 select 的對應功能。
const users = await prisma.user.findFirst({
omit: {
password: true
}
})
{
id: 9
name: "Sabelle",
email: "sabelle@prisma.io",
profileViews: 90,
role: "USER",
coinflips: [],
}
請注意返回的物件不包含 password 欄位。