关系查询
Prisma 客户端的一个关键功能是能够在两个或多个模型之间查询 relations。关系查询包括:
¥A key feature of Prisma Client is the ability to query relations between two or more models. Relation queries include:
-
通过
select
和include
的 嵌套读取(有时称为预加载)¥Nested reads (sometimes referred to as eager loading) via
select
andinclude
-
嵌套写入 和 transactional 保证
¥Nested writes with transactional guarantees
Prisma 客户端还有一个 用于遍历关系的流畅 API。
¥Prisma Client also has a fluent API for traversing relations.
嵌套读取
¥Nested reads
嵌套读取允许你从数据库中的多个表中读取相关数据 - 例如用户和该用户的帖子。你可以:
¥Nested reads allow you to read related data from multiple tables in your database - such as a user and that user's posts. You can:
-
使用
include
在查询响应中包含相关记录,例如用户的帖子或个人资料。¥Use
include
to include related records, such as a user's posts or profile, in the query response. -
使用嵌套
select
包含相关记录中的特定字段。你还可以将select
嵌套在include
内。¥Use a nested
select
to include specific fields from a related record. You can also nestselect
inside aninclude
.
关系加载策略(预览)
¥Relation load strategies (Preview)
自版本 5.8.0 以来,你可以通过 PostgreSQL 数据库的 relationLoadStrategy
选项在每个查询级别决定你希望 Prisma Client 如何执行关系查询(即应应用哪种加载策略)。
¥Since version 5.8.0, you can decide on a per-query-level how you want Prisma Client to execute a relation query (i.e. what load strategy should be applied) via the relationLoadStrategy
option for PostgreSQL databases.
自版本 5.10.0 以来,此功能也可用于 MySQL。
¥Since version 5.10.0, this feature is also available for MySQL.
由于 relationLoadStrategy
选项当前处于预览状态,因此你需要通过 Prisma 架构文件中的 relationJoins
预览功能标志启用它:
¥Because the relationLoadStrategy
option is currently in Preview, you need to enable it via the relationJoins
preview feature flag in your Prisma schema file:
generator client {
provider = "prisma-client-js"
previewFeatures = ["relationJoins"]
}
添加此标志后,你需要再次运行 prisma generate
以重新生成 Prisma Client。relationJoins
功能目前在 PostgreSQL、CockroachDB 和 MySQL 上可用。
¥After adding this flag, you need to run prisma generate
again to re-generate Prisma Client. The relationJoins
feature is currently available on PostgreSQL, CockroachDB and MySQL.
Prisma 客户端支持两种关系加载策略:
¥Prisma Client supports two load strategies for relations:
-
join
(默认):使用数据库级LATERAL JOIN
(PostgreSQL) 或相关子查询 (MySQL),并通过对数据库的单个查询获取所有数据。¥
join
(default): Uses a database-levelLATERAL JOIN
(PostgreSQL) or correlated subqueries (MySQL) and fetches all data with a single query to the database. -
query
:向数据库发送多个查询(每个表一个)并在应用级别连接它们。¥
query
: Sends multiple queries to the database (one per table) and joins them on the application level.
这两个选项之间的另一个重要区别是 join
策略在数据库级别使用 JSON 聚合。这意味着它创建的 Prisma 客户端返回的 JSON 结构已经存在于数据库中,从而节省了应用级别的计算资源。
¥Another important difference between these two options is that the join
strategy uses JSON aggregation on the database level. That means that it creates the JSON structures returned by Prisma Client already in the database which saves computation resources on the application level.
注意:一旦
relationLoadStrategy
从 预览 移动到 一般可用性,join
将普遍成为所有关系查询的默认值。¥Note: Once
relationLoadStrategy
moves from Preview into General Availability,join
will universally become the default for all relation queries.
示例
¥Examples
你可以在任何支持 include
或 select
的查询中使用顶层的 relationLoadStrategy
选项。
¥You can use the relationLoadStrategy
option on the top-level in any query that supports include
or select
.
以下是 include
的示例:
¥Here is an example with include
:
const users = await prisma.user.findMany({
relationLoadStrategy: 'join', // or 'query'
include: {
posts: true,
},
})
这是 select
的另一个例子:
¥And here is another example with select
:
const users = await prisma.user.findMany({
relationLoadStrategy: 'join', // or 'query'
select: {
posts: true,
},
})
何时使用哪种加载策略?
¥When to use which load strategy?
-
join
策略(默认)在大多数情况下会更有效。在 PostgreSQL 上,它结合使用LATERAL JOINs
和 JSON 聚合来减少结果集中的冗余,并委托将查询结果转换为数据库服务器上预期的 JSON 结构的工作。在 MySQL 上,它使用相关子查询来通过单个查询获取结果。¥The
join
strategy (default) will be more effective in most scenarios. On PostgreSQL, it uses a combination ofLATERAL JOINs
and JSON aggregation to reduce redundancy in result sets and delegate the work of transforming the query results into the expected JSON structures on the database server. On MySQL, it uses correlated subqueries to fetch the results with a single query. -
根据数据集和查询的特性,可能存在
query
性能更高的边缘情况。我们建议你分析数据库查询以识别这些情况。¥There may be edge cases where
query
could be more performant depending on the characteristics of the dataset and query. We recommend that you profile your database queries to identify these situations. -
如果你想节省数据库服务器上的资源并在应用服务器中执行繁重的数据合并和转换工作(这可能更容易扩展),请使用
query
。¥Use
query
if you want to save resources on the database server and do heavy-lifting of merging and transforming data in the application server which might be easier to scale.
包括关系
¥Include a relation
以下示例返回单个用户和该用户的帖子:
¥The following example returns a single user and that user's posts:
const user = await prisma.user.findFirst({
include: {
posts: true,
},
})
包括特定关系的所有字段
¥Include all fields for a specific relation
以下示例返回帖子及其作者:
¥The following example returns a post and its author:
const post = await prisma.post.findFirst({
include: {
author: true,
},
})
包括深层嵌套关系
¥Include deeply nested relations
你可以嵌套 include
选项以包含关系的关系。以下示例返回用户的帖子以及每个帖子的类别:
¥You can nest include
options to include relations of relations. The following example returns a user's posts, and each post's categories:
const user = await prisma.user.findFirst({
include: {
posts: {
include: {
categories: true,
},
},
},
})
选择包含关系的特定字段
¥Select specific fields of included relations
你可以使用嵌套的 select
选择要返回的关系字段子集。例如,以下查询返回用户的 name
和每个相关帖子的 title
:
¥You can use a nested select
to choose a subset of fields of relations to return. For example, the following query returns the user's name
and the title
of each related post:
const user = await prisma.user.findFirst({
select: {
name: true,
posts: {
select: {
title: true,
},
},
},
})
你还可以将 select
嵌套在 include
中 - 以下示例返回每个帖子的所有 User
字段和 title
字段:
¥You can also nest a select
inside an include
- the following example returns all User
fields and the title
field of each post:
const user = await prisma.user.findFirst({
include: {
posts: {
select: {
title: true,
},
},
},
})
请注意,你不能在同一级别上使用 select
和 include
。这意味着,如果你选择 include
用户的帖子并 select
每个帖子的标题,则不能仅 select
用户的 email
:
¥Note that you cannot use select
and include
on the same level. This means that if you choose to include
a user's post and select
each post's title, you cannot select
only the users' email
:
// The following query returns an exception
const user = await prisma.user.findFirst({
select: { // This won't work!
email: true
}
include: { // This won't work!
posts: {
select: {
title: true
}
}
},
})
相反,使用嵌套 select
选项:
¥Instead, use nested select
options:
const user = await prisma.user.findFirst({
select: {
// This will work!
email: true,
posts: {
select: {
title: true,
},
},
},
})
关系计数
¥Relation count
在 3.0.1 及更高版本中,你可以将 include
或 select
关系计数 放在字段旁边 - 例如,用户的帖子计数。
¥In 3.0.1 and later, you can include
or select
a count of relations alongside fields - for example, a user's post count.
const relationCount = await prisma.user.findMany({
include: {
_count: {
select: { posts: true },
},
},
})
过滤关系列表
¥Filter a list of relations
当你使用 select
或 include
返回相关数据的子集时,你可以对 select
或 include
内部的关系列表进行过滤和排序。
¥When you use select
or include
to return a subset of the related data, you can filter and sort the list of relations inside the select
or include
.
例如,以下查询返回与用户关联的未发布帖子的标题列表:
¥For example, the following query returns list of titles of the unpublished posts associated with the user:
const result = await prisma.user.findFirst({
select: {
posts: {
where: {
published: false,
},
orderBy: {
title: 'asc',
},
select: {
title: true,
},
},
},
})
你还可以使用 include
编写相同的查询,如下所示:
¥You can also write the same query using include
as follows:
const result = await prisma.user.findFirst({
include: {
posts: {
where: {
published: false,
},
orderBy: {
title: 'asc',
},
},
},
})
嵌套写入
¥Nested writes
嵌套写入允许你在单个事务中将关系数据写入数据库。
¥A nested write allows you to write relational data to your database in a single transaction.
嵌套写道:
¥Nested writes:
-
为在单个 Prisma 客户端查询中跨多个表创建、更新或删除数据提供事务保证。如果查询的任何部分失败(例如,创建用户成功但创建帖子失败),Prisma 客户端将回滚所有更改。
¥Provide transactional guarantees for creating, updating or deleting data across multiple tables in a single Prisma Client query. If any part of the query fails (for example, creating a user succeeds but creating posts fails), Prisma Client rolls back all changes.
-
支持数据模型支持的任何级别的嵌套。
¥Support any level of nesting supported by the data model.
-
使用模型的创建或更新查询时可用于 关系字段。以下部分显示每个查询可用的嵌套写入选项。
¥Are available for relation fields when using the model's create or update query. The following section shows the nested write options that are available per query.
创建相关记录
¥Create a related record
你可以同时创建一条记录和一条或多条相关记录。以下查询创建一条 User
记录和两条相关的 Post
记录:
¥You can create a record and one or more related records at the same time. The following query creates a User
record and two related Post
records:
const result = await prisma.user.create({
data: {
email: 'elsa@prisma.io',
name: 'Elsa Prisma',
posts: {
create: [
{ title: 'How to make an omelette' },
{ title: 'How to eat an omelette' },
],
},
},
include: {
posts: true, // Include all posts in the returned object
},
})
创建单个记录和多个相关记录
¥Create a single record and multiple related records
有两种方法可以创建或更新单个记录和多个相关记录 - 例如,具有多个帖子的用户:
¥There are two ways to create or update a single record and multiple related records - for example, a user with multiple posts:
-
使用嵌套
create
查询¥Use a nested
create
query -
使用嵌套
createMany
查询¥Use a nested
createMany
query
在大多数情况下,除非需要 skipDuplicates
查询选项,否则嵌套的 create
将是首选。这是一个快速表格,描述了两个选项之间的差异:
¥In most cases, a nested create
will be preferable unless the skipDuplicates
query option is required. Here's a quick table describing the differences between the two options:
特性 | create | createMany | 注意 |
---|---|---|---|
支持嵌套附加关系 | ✔ | ✘ * | 例如,你可以在一个查询中创建一个用户、多个帖子以及每个帖子的多个评论。 * 你可以在“有一”关系中手动设置外键 - 例如: { authorId: 9} |
支持 1-n 关系 | ✔ | ✔ | 例如,你可以创建一个用户和多个帖子(一个用户有多个帖子) |
支持 m-n 关系 | ✔ | ✘ | 例如,你可以创建一个帖子和多个类别(一个帖子可以有多个类别,一个类别可以有多个帖子) |
支持跳过重复记录 | ✘ | ✔ | 使用 skipDuplicates 查询选项。 |
使用嵌套 create
¥Using nested create
以下查询使用嵌套 create
创建:
¥The following query uses nested create
to create:
-
一名用户
¥One user
-
两个帖子
¥Two posts
-
一个帖子类别
¥One post category
该示例还使用嵌套 include
来包含返回数据中的所有帖子和帖子类别。
¥The example also uses a nested include
to include all posts and post categories in the returned data.
const result = await prisma.user.create({
data: {
email: 'yvette@prisma.io',
name: 'Yvette',
posts: {
create: [
{
title: 'How to make an omelette',
categories: {
create: {
name: 'Easy cooking',
},
},
},
{ title: 'How to eat an omelette' },
],
},
},
include: {
// Include posts
posts: {
include: {
categories: true, // Include post categories
},
},
},
})
以下是嵌套创建操作如何一次性写入数据库中的多个表的直观表示:
¥Here's a visual representation of how a nested create operation can write to several tables in the database as once:
使用嵌套 createMany
¥Using nested createMany
以下查询使用嵌套 createMany
来创建:
¥The following query uses a nested createMany
to create:
-
一名用户
¥One user
-
两个帖子
¥Two posts
该示例还使用嵌套 include
来包含返回数据中的所有帖子。
¥The example also uses a nested include
to include all posts in the returned data.
const result = await prisma.user.create({
data: {
email: 'saanvi@prisma.io',
posts: {
createMany: {
data: [{ title: 'My first post' }, { title: 'My second post' }],
},
},
},
include: {
posts: true,
},
})
请注意,无法在高亮的查询中嵌套额外的 create
或 createMany
,这意味着你无法同时创建用户、帖子和帖子类别。
¥Note that it is not possible to nest an additional create
or createMany
inside the highlighted query, which means that you cannot create a user, posts, and post categories at the same time.
作为一种解决方法,你可以发送查询以首先创建将连接的记录,然后创建实际记录。例如:
¥As a workaround, you can send a query to create the records that will be connected first, and then create the actual records. For example:
const categories = await prisma.category.createManyAndReturn({
data: [
{ name: 'Fun', },
{ name: 'Technology', },
{ name: 'Sports', }
],
select: {
id: true
}
});
const posts = await prisma.post.createManyAndReturn({
data: [{
title: "Funniest moments in 2024",
categoryId: categories.filter(category => category.name === 'Fun')!.id
}, {
title: "Linux or macOS — what's better?",
categoryId: categories.filter(category => category.name === 'Technology')!.id
},
{
title: "Who will win the next soccer championship?",
categoryId: categories.filter(category => category.name === 'Sports')!.id
}]
});
如果你想在单个数据库查询中创建所有记录,请考虑使用 $transaction
或 类型安全,原始 SQL。
¥If you want to create all records in a single database query, consider using a $transaction
or type-safe, raw SQL.
创建多条记录和多条相关记录
¥Create multiple records and multiple related records
你无法访问 createMany()
或 createManyAndReturn()
查询中的关系,这意味着你无法在单个嵌套写入中创建多个用户和多个帖子。以下情况是不可能的:
¥You cannot access relations in a createMany()
or createManyAndReturn()
query, which means that you cannot create multiple users and multiple posts in a single nested write. The following is not possible:
const createMany = await prisma.user.createMany({
data: [
{
name: 'Yewande',
email: 'yewande@prisma.io',
posts: {
// Not possible to create posts!
},
},
{
name: 'Noor',
email: 'noor@prisma.io',
posts: {
// Not possible to create posts!
},
},
],
})
连接多条记录
¥Connect multiple records
以下查询创建 (create
) 一条新的 User
记录,并将该记录 (connect
) 连接到三个现有帖子:
¥The following query creates (create
) a new User
record and connects that record (connect
) to three existing posts:
const result = await prisma.user.create({
data: {
email: 'vlad@prisma.io',
posts: {
connect: [{ id: 8 }, { id: 9 }, { id: 10 }],
},
},
include: {
posts: true, // Include all posts in the returned object
},
})
注意:如果找不到任何帖子记录,Prisma 客户端会抛出异常:
connect: [{ id: 8 }, { id: 9 }, { id: 10 }]
¥Note: Prisma Client throws an exception if any of the post records cannot be found:
connect: [{ id: 8 }, { id: 9 }, { id: 10 }]
连接单个记录
¥Connect a single record
你可以将现有记录 connect
给新用户或现有用户。以下查询将现有帖子 (id: 11
) 连接到现有用户 (id: 9
)
¥You can connect
an existing record to a new or existing user. The following query connects an existing post (id: 11
) to an existing user (id: 9
)
const result = await prisma.user.update({
where: {
id: 9,
},
data: {
posts: {
connect: {
id: 11,
},
},
},
include: {
posts: true,
},
})
连接或创建记录
¥Connect or create a record
如果相关记录可能存在也可能不存在,请使用 connectOrCreate
连接相关记录:
¥If a related record may or may not already exist, use connectOrCreate
to connect the related record:
-
将
User
与电子邮件地址viola@prisma.io
连接或¥Connect a
User
with the email addressviola@prisma.io
or -
如果用户尚不存在,则使用电子邮件地址
viola@prisma.io
创建新的User
¥Create a new
User
with the email addressviola@prisma.io
if the user does not already exist
const result = await prisma.post.create({
data: {
title: 'How to make croissants',
author: {
connectOrCreate: {
where: {
email: 'viola@prisma.io',
},
create: {
email: 'viola@prisma.io',
name: 'Viola',
},
},
},
},
include: {
author: true,
},
})
断开相关记录
¥Disconnect a related record
向 disconnect
记录列表(例如,特定博客文章)中的一个提供要断开连接的记录的 ID 或唯一标识符:
¥To disconnect
one out of a list of records (for example, a specific blog post) provide the ID or unique identifier of the record(s) to disconnect:
const result = await prisma.user.update({
where: {
id: 16,
},
data: {
posts: {
disconnect: [{ id: 12 }, { id: 19 }],
},
},
include: {
posts: true,
},
})
要 disconnect
一条记录(例如,帖子的作者),请使用 disconnect: true
:
¥To disconnect
one record (for example, a post's author), use disconnect: true
:
const result = await prisma.post.update({
where: {
id: 23,
},
data: {
author: {
disconnect: true,
},
},
include: {
author: true,
},
})
断开所有相关记录
¥Disconnect all related records
disconnect
是一对多关系中的所有相关记录(一个用户有很多帖子),set
是一个空列表的关系,如下所示:
¥To disconnect
all related records in a one-to-many relation (a user has many posts), set
the relation to an empty list as shown:
const result = await prisma.user.update({
where: {
id: 16,
},
data: {
posts: {
set: [],
},
},
include: {
posts: true,
},
})
删除所有相关记录
¥Delete all related records
删除所有相关的 Post
记录:
¥Delete all related Post
records:
const result = await prisma.user.update({
where: {
id: 11,
},
data: {
posts: {
deleteMany: {},
},
},
include: {
posts: true,
},
})
删除特定相关记录
¥Delete specific related records
通过删除所有未发布的帖子来更新用户:
¥Update a user by deleting all unpublished posts:
const result = await prisma.user.update({
where: {
id: 11,
},
data: {
posts: {
deleteMany: {
published: false,
},
},
},
include: {
posts: true,
},
})
通过删除特定帖子来更新用户:
¥Update a user by deleting specific posts:
const result = await prisma.user.update({
where: {
id: 6,
},
data: {
posts: {
deleteMany: [{ id: 7 }],
},
},
include: {
posts: true,
},
})
更新所有相关记录(或过滤器)
¥Update all related records (or filter)
你可以使用嵌套 updateMany
更新特定用户的所有相关记录。以下查询取消发布特定用户的所有帖子:
¥You can use a nested updateMany
to update all related records for a particular user. The following query unpublishes all posts for a specific user:
const result = await prisma.user.update({
where: {
id: 6,
},
data: {
posts: {
updateMany: {
where: {
published: true,
},
data: {
published: false,
},
},
},
},
include: {
posts: true,
},
})
更新特定相关记录
¥Update a specific related record
const result = await prisma.user.update({
where: {
id: 6,
},
data: {
posts: {
update: {
where: {
id: 9,
},
data: {
title: 'My updated title',
},
},
},
},
include: {
posts: true,
},
})
更新或创建相关记录
¥Update or create a related record
以下查询使用嵌套 upsert
来更新 "bob@prisma.io"
(如果该用户存在),或者创建该用户(如果不存在):
¥The following query uses a nested upsert
to update "bob@prisma.io"
if that user exists, or create the user if they do not exist:
const result = await prisma.post.update({
where: {
id: 6,
},
data: {
author: {
upsert: {
create: {
email: 'bob@prisma.io',
name: 'Bob the New User',
},
update: {
email: 'bob@prisma.io',
name: 'Bob the existing user',
},
},
},
},
include: {
author: true,
},
})
将新的相关记录添加到现有记录
¥Add new related records to an existing record
你可以将 create
或 createMany
嵌套在 update
中,以将新的相关记录添加到现有记录中。以下查询向 id
为 9 的用户添加两个帖子:
¥You can nest create
or createMany
inside an update
to add new related records to an existing record. The following query adds two posts to a user with an id
of 9:
const result = await prisma.user.update({
where: {
id: 9,
},
data: {
posts: {
createMany: {
data: [{ title: 'My first post' }, { title: 'My second post' }],
},
},
},
include: {
posts: true,
},
})
关系过滤器
¥Relation filters
筛选 "-太多" 关系
¥Filter on "-to-many" relations
Prisma 客户端提供 some
、every
和 none
选项,用于按关系 "-太多" 端相关记录的属性过滤记录。例如,根据帖子的属性过滤用户。
¥Prisma Client provides the some
, every
, and none
options to filter records by the properties of related records on the "-to-many" side of the relation. For example, filtering users based on properties of their posts.
例如:
¥For example:
要求 | 使用的查询选项 |
---|---|
“我想要一份至少有一条未发布的 Post 记录的每个 User 的列表” | some 个帖子未发布 |
“我想要一份没有未发布的 Post 记录的每个 User 的列表” | none 个帖子未发布 |
“我想要一份仅包含未发布的 Post 记录的每个 User 的列表” | every 帖子未发布 |
例如,以下查询返回满足以下条件的 User
:
¥For example, the following query returns User
that meet the following criteria:
-
没有帖子的浏览量超过 100 次
¥No posts with more than 100 views
-
所有帖子的点赞数均小于或等于 50
¥All posts have less than, or equal to 50 likes
const users = await prisma.user.findMany({
where: {
posts: {
none: {
views: {
gt: 100,
},
},
every: {
likes: {
lte: 50,
},
},
},
},
include: {
posts: true,
},
})
筛选 "一对一" 关系
¥Filter on "-to-one" relations
Prisma 客户端提供 is
和 isNot
选项,用于根据关系 "一对一" 端相关记录的属性来过滤记录。例如,根据作者的属性过滤帖子。
¥Prisma Client provides the is
and isNot
options to filter records by the properties of related records on the "-to-one" side of the relation. For example, filtering posts based on properties of their author.
例如,以下查询返回满足以下条件的 Post
条记录:
¥For example, the following query returns Post
records that meet the following criteria:
-
作者的名字不是鲍勃
¥Author's name is not Bob
-
作者年龄 40 多岁
¥Author is older than 40
const users = await prisma.post.findMany({
where: {
author: {
isNot: {
name: 'Bob',
},
is: {
age: {
gt: 40,
},
},
},
},
include: {
author: true,
},
})
过滤缺少 "-太多" 记录的情况
¥Filter on absence of "-to-many" records
例如,以下查询使用 none
返回所有帖子为零的用户:
¥For example, the following query uses none
to return all users that have zero posts:
const usersWithZeroPosts = await prisma.user.findMany({
where: {
posts: {
none: {},
},
},
include: {
posts: true,
},
})
过滤不存在 "一对一" 关系
¥Filter on absence of "-to-one" relations
以下查询返回所有没有作者关系的帖子:
¥The following query returns all posts that don't have an author relation:
const postsWithNoAuthor = await prisma.post.findMany({
where: {
author: null, // or author: { }
},
include: {
author: true,
},
})
过滤相关记录的存在
¥Filter on presence of related records
以下查询返回至少拥有一篇帖子的所有用户:
¥The following query returns all users with at least one post:
const usersWithSomePosts = await prisma.user.findMany({
where: {
posts: {
some: {},
},
},
include: {
posts: true,
},
})
流畅的 API
¥Fluent API
流畅的 API 让你可以通过函数调用流畅地遍历模型的 relations。请注意,最后一个函数调用确定整个查询的返回类型(在下面的代码片段中添加相应的类型注释以使其明确)。
¥The fluent API lets you fluently traverse the relations of your models via function calls. Note that the last function call determines the return type of the entire query (the respective type annotations are added in the code snippets below to make that explicit).
此查询返回特定 User
的所有 Post
记录:
¥This query returns all Post
records by a specific User
:
const postsByUser: Post[] = await prisma.user
.findUnique({ where: { email: 'alice@prisma.io' } })
.posts()
这相当于以下 findMany
查询:
¥This is equivalent to the following findMany
query:
const postsByUser = await prisma.post.findMany({
where: {
author: {
email: 'alice@prisma.io',
},
},
})
查询之间的主要区别在于,流畅的 API 调用被转换为两个单独的数据库查询,而另一个仅生成单个查询(请参阅此 GitHub 问题)
¥The main difference between the queries is that the fluent API call is translated into two separate database queries while the other one only generates a single query (see this GitHub issue)
注意:你可以利用 Prisma 客户端中的 Prisma 数据加载器自动将
.findUnique({ where: { email: 'alice@prisma.io' } }).posts()
查询批量批处理到 避免 GraphQL 解析器中的 n+1 问题 的事实。¥Note: You can use the fact that
.findUnique({ where: { email: 'alice@prisma.io' } }).posts()
queries are automatically batched by the Prisma dataloader in Prisma Client to avoid the n+1 problem in GraphQL resolvers.
此请求返回特定帖子的所有类别:
¥This request returns all categories by a specific post:
const categoriesOfPost: Category[] = await prisma.post
.findUnique({ where: { id: 1 } })
.categories()
请注意,你可以根据需要链接任意数量的查询。在此示例中,链接从 Profile
开始,经过 User
到 Post
:
¥Note that you can chain as many queries as you like. In this example, the chaining starts at Profile
and goes over User
to Post
:
const posts: Post[] = await prisma.profile
.findUnique({ where: { id: 1 } })
.user()
.posts()
链接的唯一要求是先前的函数调用必须仅返回单个对象(例如,由 findUnique
查询或 "一对一关系"(如 profile.user()
)返回)。
¥The only requirement for chaining is that the previous function call must return only a single object (e.g. as returned by a findUnique
query or a "to-one relation" like profile.user()
).
以下查询是不可能的,因为 findMany
不返回单个对象而是一个列表:
¥The following query is not possible because findMany
does not return a single object but a list:
// This query is illegal
const posts = await prisma.user.findMany().posts()