select与include
select:选择特定字段,可以嵌套select使用,减少数据量
include:包含关联数据,返回完整的关联对象
两者都是用于返回一些数据,只是返回的数据不同。select返回指定字段,可以选标量字段,也可以选择关系字段,而include不能选标量字段,只能包含关系。
注意:使用时select与include不能平级在同一层使用
使用上的一个方式:关系内部可以继续使用where、orderBy、select、include
准备一份数据,代码如下:
javascript
// seed.js
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function main() {
await prisma.post.deleteMany()
await prisma.user.deleteMany()
await prisma.user.create({
data: {
email: 'alice@example.com',
name: 'Alice',
password: 'hashed_pwd_1',
posts: {
create: [
{ title: 'Hello Prisma', content: 'first post', published: true },
{ title: 'Draft post', content: 'not ready', published: false },
],
},
},
})
}
main().finally(() => prisma.$disconnect())
使用select与include,代码如下:
javascript
// index.js
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function main() {
// ---------- 1. 什么都不加:只有 User 自身字段 ----------
const plain = await prisma.user.findMany()
console.log('1. 默认:', JSON.stringify(plain, null, 2))
// ---------- 2. include:User 全部字段 + posts ----------
const withInclude = await prisma.user.findMany({
include: { posts: true },
})
console.log('2. include:', JSON.stringify(withInclude, null, 2))
// ---------- 3. select:只要列出的字段 ----------
const withSelect = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: true, // 关联关系也可以写在 select 里
},
})
console.log('3. select:', JSON.stringify(withSelect, null, 2))
}
main().finally(() => prisma.$disconnect())
看下下面数据输出的区别如下:
默认(没有select与include),输出如下:
javascript
[
{
"id": 1,
"email": "alice@example.com",
"name": "Alice",
"password": "hashed_pwd_1",
"createdAt": "2024-05-01T10:00:00.000Z"
}
]
使用select,输出如下:
javascript
[
{
"id": 1,
"name": "Alice",
"posts": [
{
"id": 1,
"title": "Hello Prisma",
"content": "first post",
"published": true,
"authorId": 1
},
{
"id": 2,
"title": "Draft post",
"content": "not ready",
"published": false,
"authorId": 1
}
]
}
]
使用include,代码结果如下:
javascript
[
{
"id": 1,
"email": "alice@example.com",
"name": "Alice",
"password": "hashed_pwd_1",
"createdAt": "2024-05-01T10:00:00.000Z",
"posts": [
{
"id": 1,
"title": "Hello Prisma",
"content": "first post",
"published": true,
"authorId": 1
},
{
"id": 2,
"title": "Draft post",
"content": "not ready",
"published": false,
"authorId": 1
}
]
}
]
一般在实际的生产项目中会混合嵌套使用,比如像下面的代码:
javascript
// include 里嵌 select(限制关联字段)
const a = await prisma.user.findMany({
include: {
posts: {
select: { title: true, published: true },
},
},
})
// 结果:User 全字段 + posts: [{ title, published }, ...]
// select 里嵌 include
const b = await prisma.user.findMany({
select: {
id: true,
posts: {
include: { author: { select: { email: true } } },
},
},
})
// 结果:只有 id + posts(全字段 + author.email)
// 嵌套里加 where / orderBy / take
const c = await prisma.user.findMany({
select: {
id: true,
posts: {
where: { published: true },
orderBy: { id: 'desc' },
take: 5,
select: { title: true },
},
},
})