Reading Data (JavaScript)
Overview
The Prisma client is based on the operations defined in the GraphQL schema of your Prisma API. For reading data, it basically mirrors the GraphQL queries of your Prisma service.
For this page, we'll assume your Prisma API is based on the following datamodel:
type Link {
id: ID! @unique
createdAt: DateTime!
description: String!
url: String!
postedBy: User
votes: [Vote!]!
}
type User {
id: ID! @unique
name: String!
email: String! @unique
password: String!
links: [Link!]!
votes: [Vote!]!
}
type Vote {
id: ID! @unique
link: Link!
user: User!
}
Whenever a model is queried using the Prisma client, all scalar fields of that model are fetched. This is true no matter if a single object or a list of objects is queried.
For example, the following query returns all scalar fields of a single User
:
const user = await prisma.user({ email: 'bob@prisma.io' })
In this case, the returned user
object will have four properties (that correspond to the scalar fields of the User
model): id
, name
, email
and password
.
The links
and votes
fields are both relation fields and are therefore not included in the query.
Here is an example of fetching a list of User
objects:
const users = await prisma.users()
Similar to the previous query, each object inside the users
array only has the scalar and no relation fields.
Fetching single objects
For each model type in your datamodel, there is a method generated in the Prisma client API that allows to fetch single objects of that model. The method is named after the type but starts with a lowercase character. For the sample datamodel from above, the three methods for fetching single User
, Link
and Vote
objects are called user
, link
and vote
.
The input for these functions is an object that has as properties any unique field of the model. This means, for all three methods, the id
field is accepted (as the corresponding models each have an id
field annotated as @unique
). The input object for the user
method additionaly has an email
field.
Examples
Fetch a single vote by its id:
const vote = await prisma.vote({ id: 'cjlgpyueg001o0a239d3i07ao' })
Copy
Fetch a single user by their email:
const user = await prisma.user({ email: 'alice@prisma.io' })
Copy
Fetching lists
For each model type in your datamodel, there is a method generated in the Prisma client API that allows to fetch a list of those model objects. The method is named after the model but starts with a lowercase character and uses the plural form. For the sample datamodel from above, the three methods for fetching lists of User
, Link
and Vote
models are called users
, links
and votes
.
The input arugment for these functions is an object that has properties for:
- Filtering:
where
- Ordering:
orderBy
- Pagination:
before
,after
,first
,last
,skip
Examples
Fetch all links:
const links = await prisma.links()
Copy
Fetch a list of users:
const users = await prisma.users()
Copy
Relations
Prisma client has a fluent API to query relations in your data graph. Meaning you can simply chain your method calls to navigate the relation properties of the returned models.
This is only possible when retrieving single objects, not for lists. Meaning you can not query relation fields of objects that are returned in a list, e.g.:
// not possible
const result = await prisma.users().links()
In this example, users()
already returns a list, so it's not possible to query the links
relation of each user object inside the list.
Examples
Query all the links of a single user:
const linksByUser = await prisma.user({ email: 'alice@prisma.io' }).links()
Copy
Query all the votes made by a certain user:
const votesByUser = await prisma.user({ email: 'alice@prisma.io' }).votes()
Copy
Using fragments for fine-grained data access
Instead of querying all scalar fields of a model (which is the default behavior), you can specify which fields you'd like retrieve by using the $fragment
API feature (based on GraphQL). This is useful to exclude large unneeded fields (like BLOB values or huge strings) or to even retrieve relations.
Examples
Fetch the name
and email
of the users as well the the description
and url
of their related links:
const fragment = ` fragment UserWithLinks on User { name email links { description url } } ` const userWithPosts = await prisma.users().$fragment(fragment)
Copy
Basic filters for lists
Basic filters let you specify certain criteria to constrain which objects should be returned in a list. The filters are specified in the where
object of the input argument which is accepted by any list query.
The type of the where
object depends on the model for which it was generated.
It is also possible to combine multiple filters using the AND
and OR
fields.
Examples
Fetch users that have an A
in their names:
const usersWithAInName = await prisma.users({ where: { name_contains: 'A', }, })
Copy
Fetch users called Alice
or Bob
:
const usersCalledAliceOrBob = await prisma.users({ where: { name_in: ['Alice', 'Bob'], }, })
Copy
Fetch links created before December 24, 2018:
const linksBeforeChristmas = await prisma.links({ where: { createdAt_lt: '2018-12-24', }, })
Copy
Dates and times in the Prisma client API follow the ISO 8601 standard which generally is of the form:
YYYY-MM-DDThh:mm:ss
. Learn more.
Fetch links that have prisma
or graphql
in their description and were created in 2018:
const filteredLinks = await prisma.links({ where: { AND: [ { OR: [ { description_contains: 'graphql', }, { description_contains: 'prisma', }, ], }, { AND: [ { createdAt_gt: '2017', }, { createdAt_lt: '2019', }, ], }, ], }, })
Copy
The AND
filter can actually be omitted since multiple filter criteria are by default combined using a logical and. This means the above filter can also be expressed as follows:
const filteredLinks = await prisma.links({ where: { OR: [ { description_contains: 'graphql', }, { description_contains: 'prisma', }, ], createdAt_gt: '2017', createdAt_lt: '2019', }, })
Copy
Relational filters for lists
Relational filters can be used to constrain the returned objects on a relation list field. The types used for filtering are identical to basic filters, the only difference is that the filters are not applied on the first level of the method call but when querying a relation on the second level.
Examples
const linksByUserBeforeChristmas = await prisma .user({ email: 'alice@prisma.io' }) .links({ where: { createdAt_lt: '2017-12-24', }, })
Copy
Ordering
When querying a list of model objects, you can order (sort) the list by any scalar field of that model type. Each generated method to query a list of models therefore accepts the orderBy
field on its input object.
The type of the orderBy
field depends on the scalar fields of the model for which it was generated.
Examples
Sort links by their creation date (ascending):
const sortedLinks = prisma.links({ orderBy: 'createdAt_ASC', })
Copy
Sort users alphabetically by their names (descending):
const sortedUsers = prisma.users({ orderBy: 'name_DESC', })
Copy
Pagination
When querying a list of model objects, you can fetch chunks of that list by supplying pagination arguments.
Seeking forward and backward with first
and last
You can seek forwards or backwards through the objects and supply an optional starting object:
- To seek forward, use
first
; specify a starting object withafter
. - To seek backward, use
last
; specify a starting object withbefore
.
You cannot combine first
with before
or last
with after
. If you do so in a query, before
/after
will simply be ignored and only first
or last
is actually applied (at the very beginning or end of the list, depending on which you're using).
Note that you can query for more objects than actually exist in the database without an error message.
Skipping elements with skip
You can also skip an arbitrary amount of objects in whichever direction you are seeking by supplying the skip
argument:
- When using
first
,skip
skips objects at the beginning of the list. - When using
last
,skip
skips objects from the end of the list.
Examples
For the following examples, we're assuming a list of exactly 30 objects:
Query the first 3 links (seeking forward):
const links = await prisma.links({ first: 3, })
Copy
Query the objects from position 6 to position 10 (seeking forward):
const links = await prisma.links({ first: 5, skip: 5, })
Copy
Query the last 3 objects (seeking backward):
const links = await prisma.links({ last: 3, })
Copy
Query the objects from position 21 to position 27 (seeking backward):
const links = await prisma.links({ last: 7, skip: 3, })
Copy
Query the first 3 objects after the object with cixnen24p33lo0143bexvr52n
as id
:
const links = await prisma.links({ first: 3, after: 'cixnen24p33lo0143bexvr52n', })
Copy
Query the first 5 objects after the object with cixnen24p33lo0143bexvr52n
as id
and skipping 3 objects:
const links = await prisma.links({ first: 5, after: 'cixnen24p33lo0143bexvr52n', skip: 3, })
Copy
Query the last 5 objects before the object with cixnen24p33lo0143bexvr52n
as id
:
const links = await prisma.links({ last: 5, before: 'cixnen24p33lo0143bexvr52n', })
Copy
Query the last 3 nodes before the node with cixnen24p33lo0143bexvr52n as id and skipping 5 nodes:
const links = await prisma.links({ last: 3, before: 'cixnen24p33lo0143bexvr52n', skip: 5, })
Copy
Aggregations
You can submit aggregation queries via connection queries. The following aggregation functions are supported:
count
: Counts the number of objects in a listavg
(coming soon): Computes the average of a list of numbers.median
(coming soon): Computes the median of a list of numbers.max
(coming soon): Returns the greatest element of a list of numbers.min
(coming soon): Returns the smallest element of a list of numbers.sum
(coming soon): Computes the sum of a list of numbers.
See this GitHub issue to learn more about the upcoming aggregation functions.
Examples
Count the number of link objects:
const linkCount = await prisma .linksConnection() .aggregate() .count()
Copy