Overview

This section explains how to predict and control which fields of a model are returned in a Prisma Client API call by using the select and include options.

Unless otherwise noted, the examples on this page are based on the following Prisma schema:

1model User {
2 id Int @id @default(autoincrement())
3 name String?
4 email String @unique
5 profileViews Int @default(0)
6 role Role @default(USER)
7 coinflips Boolean[]
8 posts Post[]
9}
10
11model Post {
12 id Int @id @default(autoincrement())
13 title String
14 published Boolean @default(true)
15 author User @relation(fields: [authorId], references: [id])
16 authorId Int
17}
18
19enum Role {
20 USER
21 ADMIN
22}

Selection sets

To understand which fields are being returned by a certain Prisma Client query, you need to be aware of its selection set.

The selection set defines which object properties the Prisma Client API call returns.

Consider the following example findOne invocation:

1const result = await prisma.user.findOne({
2 where: { id: 1 },
3})

The result of this API call is a plain old JavaScript object that might look similar to this:

1{
2 id: 1,
3 name: "Alice",
4 email: "alice@prisma.io",
5 profileViews: 0,
6 role: "ADMIN",
7 coinflips: [true, false],
8}

All the fields that are contained in this object are scalar fields, enums or arrays of scalar fields.

The default selection set

If the selection set is not manipulated (via select or include), a Prisma Client API call returns the default selection set for a model. It includes all scalar fields (including enums and arrays/scalar lists) fields of the model.

Considering the sample datamodel from above:

  • The default selection set for the User model includes id, name, email, profileViews, role and coinflips. It does not include posts because that's a relation and not a scalar field.
  • The default selection set for the Post model includes id, title and published. It does not include author because that's a relation and not a scalar field.

Manipulating the selection set

There are two ways how the default selection set can be manipulated to specify which fields should be returned by a Prisma Client API call:

  • Select exclusively (via select): When using select, the selection set only contains the fields that are explicitly provided as arguments to select.
  • Include additionally (via include): When using include, the default selection set gets extended with additional fields that are provided as arguments to include.

Note that you can nest select and include statements but they can't be provided right next to ech other. For example, the following combination is allowed:

1const result = await prisma.user.findMany({
2 select: {
3 id: true,
4 name: true,
5 posts: {
6 include: {
7 author: true,
8 },
9 },
10 },
11})

And the following one is not allowed because select and include appear on the same level of nesting right next to each other:

1const result = await prisma.user.findMany({
2 select: {
3 id: true,
4 name: true,
5 },
6 include: {
7 posts: true,
8 },
9})

This case would be caught with the following exceptions:

1Invalid `prisma.user.findMany()` invocation:
2
3{
4 select: {
5 ~~~~~~
6 id: true,
7 name: true
8 },
9 include: {
10 ~~~~~~~
11 posts: true
12 }
13}
14
15
16Please either use `include` or `select`, but not both at the same time.

Both, select and include are available as options on the following methods:

select

When providing the select option to a Prisma Client API call, only those fields are included on the returned object that are explicitly specified. The select option is an object that contains all fields of a model with a boolean value indicating whether this field should be included in the response.

Type

The type of the select option is custom for each model. For example, for the User and Post models from above the types look as follows:

1export type UserSelect = {
2 id?: boolean
3 name?: boolean
4 email?: boolean
5 role?: boolean
6 coinflips?: boolean
7 profileViews?: boolean
8 posts?: boolean | FindManyPostArgs
9}
10
11export type PostSelect = {
12 id?: boolean
13 title?: boolean
14 published?: boolean
15 author?: boolean | UserArgs
16}

The types also contain relation fields which can be even further controlled with specific arguments:

1export type UserArgs = {
2 select?: UserSelect | null
3 include?: UserInclude | null
4}
5
6export type FindManyPostArgs = {
7 select?: PostSelect | null
8 include?: PostInclude | null
9 where?: PostWhereInput | null
10 orderBy?: PostOrderByInput | null
11 skip?: number | null
12 after?: PostWhereUniqueInput | null
13 before?: PostWhereUniqueInput | null
14 first?: number | null
15 last?: number | null
16}

Examples

In this example, we're using select to exclusively select the name field of the returned User object:

1const result = await prisma.user.findOne({
2 where: { id: 1 },
3 select: {
4 name: true,
5 profileViews: true,
6 },
7})

The result object now looks as follows:

1{
2 name: "Alice",
3 profileViews: 0
4}

You can do the same on any other query listed above, e.g. on findMany:

1const result = await prisma.user.findMany({
2 select: {
3 email: true,
4 role: true,
5 },
6})

Since findMany returns an array of objects, result would now look as follows:

1;[
2 {
3 email: 'alice@prisma.io',
4 role: 'ADMIN',
5 },
6 {
7 email: 'bob@prisma.io',
8 role: 'USER',
9 },
10]

Here's how you can include additional fields of a relation:

1const result = await prisma.user.findMany({
2 select: {
3 id: true,
4 name: true,
5 posts: {
6 select: {
7 id: true,
8 title: true,
9 },
10 },
11 },
12})

In this case, the result might look as follow:

1;[
2 {
3 id: 1,
4 name: 'Alice',
5 posts: [
6 { id: 1, title: 'Hello World' },
7 { id: 2, title: 'Bye bye' },
8 ],
9 },
10 {
11 id: 2,
12 name: 'Bob',
13 posts: [],
14 },
15]

You can also nest the include option inside of the select option:

1const result = await prisma.user.findMany({
2 select: {
3 id: true,
4 name: true,
5 posts: {
6 include: {
7 author: true,
8 },
9 },
10 },
11})

This would result in the following structure for the result object:

1;[
2 {
3 id: 1,
4 name: 'Alice',
5 posts: [
6 {
7 id: 1,
8 title: 'Hello World',
9 published: true,
10 author: {
11 id: 1,
12 name: 'Alice',
13 email: 'alice@prisma.io',
14 role: 'ADMIN',
15 coinflips: [true, false],
16 profileViews: 0,
17 },
18 },
19 {
20 id: 2,
21 title: 'Bye bye',
22 published: false,
23 author: {
24 id: 1,
25 name: 'Alice',
26 email: 'alice@prisma.io',
27 role: 'USER',
28 coinflips: [],
29 profileViews: 0,
30 },
31 },
32 ],
33 },
34]

Note that the author contains all fields of the User model's default selection set (scalars, arrays/scalar lists, enums).

include

Sometimes you want to directly include a relation when retrieving data from a database (this is sometimes called "eager loading"). To include the relations of a model in an API call, you can use the include options.

Type

The type of the include option is custom for each model. For example, for the User and Post models from above the types look as follows:

1export type UserInclude = {
2 posts?: boolean | FindManyPostArgs
3}
4
5export type PostInclude = {
6 author?: boolean | UserArgs
7}

The types contain only relation fields which can be even further controlled with specific arguments:

1export type UserArgs = {
2 select?: UserSelect | null
3 include?: UserInclude | null
4}
5
6export type FindManyPostArgs = {
7 select?: PostSelect | null
8 include?: PostInclude | null
9 where?: PostWhereInput | null
10 orderBy?: PostOrderByInput | null
11 skip?: number | null
12 after?: PostWhereUniqueInput | null
13 before?: PostWhereUniqueInput | null
14 first?: number | null
15 last?: number | null
16}

Examples

1const result = await prisma.user.findOne({
2 where: { id: 1 },
3 include: { posts: true },
4})

The result object in this case contains the default selection set of the User model plus its posts relation:

1{
2 id: 1,
3 name: "Alice",
4 email: "alice@prisma.io",
5 role: "ADMIM",
6 coinflips: [true],
7 profileViews: 0,
8 posts: [
9 {
10 id: 1,
11 title: "Hello World",
12 published: true
13 },
14 {
15 id: 2,
16 title: "Bye bye",
17 published: false
18 }
19 ]
20}

You can also nest include and select statements:

1const result = await prisma.user.findOne({
2 where: { id: 1 },
3 include: {
4 posts: {
5 select: {
6 published: true,
7 title: true,
8 },
9 },
10 },
11})

This would lead to the following structure of the result object:

1{
2 id: 1,
3 name: "Alice",
4 email: "alice@prisma.io",
5 role: "USER",
6 coinflips: [true],
7 profileViews: 0,
8 posts: [
9 {
10 published: true,
11 title: "Hello World"
12 },
13 {
14 published: false,
15 title: "Bye bye"
16 }
17 ]
18}

The nesting and combinations can be arbitrarily deep:

1const result = await prisma.user.findOne({
2 where: { id: 1 },
3 include: {
4 posts: {
5 select: {
6 published: true,
7 title: true,
8 author: {
9 select: {
10 id: true,
11 posts: {
12 select: {
13 title: true,
14 },
15 },
16 },
17 },
18 },
19 },
20 },
21})

In this case, the result object would look as follows:

1{
2 id: 1,
3 name: "Alice",
4 email: "alice@prisma.io",
5 role: "USER",
6 coinflips: [true],
7 profileViews: 0,
8 posts: [
9 {
10 published: true,
11 title: "Hello World",
12 author: {
13 id: 1,
14 posts: [
15 {
16 title: "Hello World"
17 },
18 {
19 title: "Bye bye"
20 }
21 ]
22 }
23 },
24 {
25 published: false,
26 title: "Bye bye",
27 author: {
28 id: 1,
29 posts: [
30 {
31 title: "Hello World"
32 },
33 {
34 title: "Bye bye"
35 }
36 ]
37 }
38 }
39 ]
40}
Edit this page on Github