跳到主要内容

选择字段

概览

默认情况下,当查询返回记录(而不是计数)时,结果包含

  • 模型的所有标量字段(包括枚举)
  • 模型上定义的无关系

例如,考虑以下 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 模型的查询将包含 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 来决定是使用数据库级别的连接还是执行多次查询并在应用程序级别合并数据。此功能目前处于预览阶段,您可以在此处了解更多信息。

示例 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 返回字段的子集,而不是所有字段。以下示例仅返回 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 关系的计数以及字段。例如,用户的帖子数量。