选择字段
概述
默认情况下,当查询返回记录(而不是计数)时,结果将包含
- 模型的所有标量字段(包括枚举)
- 模型上未定义的关系
例如,考虑以下模式
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: "[email protected]",
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: "[email protected]",
password: "mySecretPassword42"
role: "ADMIN",
coinflips: [true, false],
}
选择特定字段
使用 select
返回字段的子集,而不是所有字段。以下示例仅返回 email
和 name
字段
const user = await prisma.user.findFirst({
select: {
email: true,
name: true,
},
})
{
name: "Alice",
email: "[email protected]",
}
通过选择关系字段返回嵌套对象
您还可以通过在 关系字段 上多次嵌套 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: "[email protected]",
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: "[email protected]",
password: "mySecretPassword4",
profileViews: 90,
role: "USER",
coinflips: [],
}
请注意返回的对象不包含 password
字段。