選取欄位
概觀
預設情況下,當查詢傳回記錄(而非計數)時,結果會包含
- 模型的所有純量欄位(包括列舉)
- 模型上定義的無關聯
舉例來說,考慮以下結構描述
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
欄位。
在這些情況下,您可以使用 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
欄位。