跳到主要內容

選取欄位

概觀

預設情況下,當查詢傳回記錄(而非計數)時,結果會包含

  • 模型的所有純量欄位(包括列舉)
  • 模型上定義的無關聯

舉例來說,考慮以下結構描述

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 模型的查詢將包含 idemailnamerole 欄位(因為這些是純量欄位),但不包含 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 來傳回欄位的子集,而不是所有欄位。以下範例僅傳回 emailname 欄位

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" }
]
}

您可以任意深度地巢狀查詢。以下查詢擷取

  • Posttitle
  • 相關 Username
  • 相關 Profilebiography
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 欄位。

關聯計數

3.0.1 和更高版本中,您可以 includeselect 關聯的計數 以及欄位。例如,使用者的貼文計數。