Skip to main content

选择字段

概述

¥Overview

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

¥By default, when a query returns records (as opposed to a count), the result includes:

  • 模型的所有标量字段(包括枚举)

    ¥All scalar fields of a model (including enums)

  • 模型上没有定义关系

    ¥No relations defined on a model

作为示例,请考虑以下模式:

¥As an example, consider this 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 字段(因为那是关系字段):

¥A query to the User model will include the id, email, name and role fields (because these are scalar fields), but not the posts field (because that's a relation field):

const users = await prisma.user.findFirst()
Show query results
{
id: 42,
name: "Sabelle",
email: "sabelle@prisma.io",
role: "ADMIN"
}

如果你想要自定义结果并返回不同的字段组合,你可以:

¥If you want to customize the result and have a different combination of fields returned, you can:

  • 使用 select 返回特定字段。你还可以通过选择关系字段来使用 嵌套 select

    ¥Use select to return specific fields. You can also use a nested select by selecting relation fields.

  • 使用 omit 从结果中排除特定字段。omit 可以看作是 "opposite" 到 select

    ¥Use omit to exclude specific fields from the result. omit can be seen as the "opposite" to select.

  • 使用 include 来附加 包括关系

    ¥Use include to additionally include relations.

在所有情况下,查询结果都将是静态类型的,确保你不会意外访问你实际上未从数据库查询的任何字段。

¥In all cases, the query result will be statically typed, ensuring that you don't accidentally access any fields that you did not actually query from the database.

仅选择你需要的字段和关系,而不是依赖默认选择集,可以减少响应的大小并提高查询速度。

¥Selecting only the fields and relations that you require rather than relying on the default selection set can reduce the size of the response and improve query speed.

从版本 5.9.0 开始,当使用 include 或在关系字段上使用 select 进行关系查询时,你还可以指定 relationLoadStrategy 来决定是否要使用数据库级联接或在应用级执行多个查询并合并数据 。该功能目前在 预览 中,你可以在 此处 中了解更多信息。

¥Since version 5.9.0, when doing a relation query with include or by using select on a relation field, you can also specify the relationLoadStrategy to decide whether you want to use a database-level join or perform multiple queries and merge the data on the application level. This feature is currently in Preview, you can learn more about it here.

示例架构

¥Example schema

本页上的所有示例均基于以下模式:

¥All following examples on this page are based on the following 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
}

返回默认字段

¥Return the default fields

以下查询返回默认字段(所有标量字段,无关系):

¥The following query returns the default fields (all scalar fields, no relations):

const user = await prisma.user.findFirst()
Show query results
{
id: 22,
name: "Alice",
email: "alice@prisma.io",
password: "mySecretPassword42"
role: "ADMIN",
coinflips: [true, false],
}

选择特定字段

¥Select specific fields

使用 select 返回字段子集而不是所有字段。以下示例仅返回 emailname 字段:

¥Use select to return a subset of fields instead of all fields. The following example returns the email and name fields only:

const user = await prisma.user.findFirst({
select: {
email: true,
name: true,
},
})
Show query results
{
name: "Alice",
email: "alice@prisma.io",
}

通过选择关系字段返回嵌套对象

¥Return nested objects by selecting relation fields

你还可以通过在 关系字段 上多次嵌套 select 来返回关系。

¥You can also return relations by nesting select multiple times on relation fields.

以下查询使用嵌套的 select 来选择每个用户的 name 和每个相关帖子的 title

¥The following query uses a nested select to select each user's name and the title of each related post:

const usersWithPostTitles = await prisma.user.findFirst({
select: {
name: true,
posts: {
select: { title: true },
},
},
})
Show query results
{
"name":"Sabelle",
"posts":[
{ "title":"Getting started with Azure Functions" },
{ "title":"All about databases" }
]
}

以下查询在 include 中使用 select,并返回所有用户字段和每个帖子的 title 字段:

¥The following query uses select within an include, and returns all user fields and each post's title field:

const usersWithPostTitles = await prisma.user.findFirst({
include: {
posts: {
select: { title: true },
},
},
})
Show query results
{
id: 9
name: "Sabelle",
email: "sabelle@prisma.io",
password: "mySecretPassword42",
role: "USER",
coinflips: [],
posts:[
{ title:"Getting started with Azure Functions" },
{ title:"All about databases" }
]
}

你可以任意深度嵌套查询。以下查询获取:

¥You can nest your queries arbitrarily deep. The following query fetches:

  • Posttitle

    ¥the title of a Post

  • 相关 Username

    ¥the name of the related User

  • 相关 Profilebiography

    ¥the biography of the related Profile

const postsWithAuthorsAndProfiles = await prisma.post.findFirst({
select: {
title: true,
author: {
select: {
name: true,
profile: {
select: { biography: true }
}
},
},
},
})
Show query results
{
id: 9
title:"All about databases",
author: {
name: "Sabelle",.
profile: {
biography: "I like turtles"
}
}
}
注意

深度嵌套关系时要小心,因为底层数据库查询可能会因需要访问许多不同的表而变慢。为确保你的查询始终具有最佳速度,请考虑使用 Prisma 加速 添加缓存层或使用 Prisma 优化 获取查询见解和性能优化建议。

¥Be careful when deeply nesting relations because the underlying database query may become slow due it needing to access a lot of different tables. To ensure your queries always have optimal speed, consider adding a caching layer with Prisma Accelerate or use Prisma Optimize to get query insights and recommendations for performance optimizations.

有关查询关系的更多信息,请参阅以下文档:

¥For more information about querying relations, refer to the following documentation:

省略特定字段

¥Omit specific fields

在某些情况下,你可能希望返回模型的大多数字段,而仅排除一小部分。一个常见的例子是当你查询 User 但出于安全原因想要排除 password 字段时。

¥There may be situations when you want to return most fields of a model, excluding only a small subset. A common example for this is when you query a User but want to exclude the password field for security reasons.

在这些情况下,你可以使用 omit,它可以看作是 select 的对应项:

¥In these cases, you can use omit, which can be seen as the counterpart to select:

const users = await prisma.user.findFirst({
omit: {
password: true
}
})
Show query results
{
id: 9
name: "Sabelle",
email: "sabelle@prisma.io",
profileViews: 90,
role: "USER",
coinflips: [],
}

请注意返回的对象不包含 password 字段。

¥Notice how the returned object does not contain the password field.

关系计数

¥Relation count

3.0.1 及更高版本中,你可以将 includeselect关系计数 与字段一起使用。例如,用户的帖子数。

¥In 3.0.1 and later, you can include or select a count of relations alongside fields. For example, a user's post count.