Find
The find series of APIs are used to query records from the database. It has the following methods:
-
findManyFind multiple records that match the query criteria.
-
findUniqueFind a single record with a unique criteria.
-
findFirstFind the first record that matches the query criteria.
-
findUniqueOrThrowSimilar to
findUnique, but throws an error if no record is found. -
findFirstOrThrowSimilar to
findFirst, but throws an error if no record is found.
Basic usage​
import { ORMError } from '@zenstackhq/orm';
import { createClient } from '../db';
import { createPosts } from '../utils';
// basic find demo
async function main() {
const db = await createClient();
// create some test posts
await createPosts(db);
// `findMany` reads a list of entities
console.log('Posts with viewCount > 0');
console.log(await db.post.findMany({ where: { viewCount: { gt: 0 } } }));
// `findUnique` takes unique criteria as input
// e.g., you can use id field
console.log('Unique post with id #1');
console.log(await db.post.findUnique({ where: { id: 1 } }));
// or any unique field
console.log('Unique post with slug "post1"');
console.log(await db.post.findUnique({ where: { slug: 'post1' } }));
// `findFirst` accepts arbitrary filter conditions that don't have
// to be unique
console.log('A published post');
console.log(await db.post.findFirst({ where: { published: true } }));
// `findUniqueOrThrow` and `findFirstOrThrow` throws an error if
// no entity is found
try {
await db.post.findUniqueOrThrow({ where: { id: 3 } });
} catch (err) {
console.log('Got an expected error:', (err as ORMError).message);
}
}
main();
Filtering​
The API provides a very flexible set of filtering options. We've put it into a dedicated document.
Sorting​
Use the orderBy field to control the sort field, direction, and null field placement. Sorting is not supported for findUnique and findUniqueOrThrow.
import { createClient } from '../db';
import { createUsersAndPosts } from '../utils';
// sort demo
async function main() {
const db = await createClient();
// create some test posts
await createUsersAndPosts(db);
// sort by a simple field and direction
console.log('Posts sorted by viewCount asc');
console.log(
await db.post.findMany({
orderBy: { viewCount: 'asc' },
select: { title: true, viewCount: true }
})
);
// sort by multiple fields
console.log('Posts sorted by publised asc, viewCount desc');
console.log(
await db.post.findMany({
orderBy: { published: 'asc', viewCount: 'desc' },
select: { title: true, published: true, viewCount: true }
})
);
// sort by a relation field
console.log('Posts osrted by author email desc');
console.log(
await db.post.findMany({
orderBy: { author: { email: 'desc' } },
select: { title: true, author: { select: { email: true } } }
})
);
// sort by the count of a to-many relation
console.log('Users sorted by post count desc');
console.log(
await db.user.findMany({
orderBy: { posts: { _count: 'desc' } },
select: { email: true, _count: true }
})
);
// sort and specify treatment of NULL values
console.log('Posts sorted by authorId nulls first');
console.log(
await db.post.findMany({
orderBy: { authorId: { sort: 'asc', nulls: 'first' } },
select: { title: true, authorId: true }
})
);
}
main();
Pagination​
You can use two strategies for pagination: offset-based or cursor-based. Pagination is not supported for findUnique and findUniqueOrThrow.
import { createClient } from '../db';
import { createUsersAndPosts } from '../utils';
// pagination demo
async function main() {
const db = await createClient();
// create some test posts
await createUsersAndPosts(db);
// use `skip` and `take` to fetch a page
console.log('The 2nd and 3nd most viewed posts');
console.log(
await db.post.findMany({
orderBy: { viewCount: 'desc' },
skip: 1,
take: 2
})
);
// you can use negative `take` to fetch backward
console.log('The top 2 most viewed posts');
console.log(
await db.post.findMany({
orderBy: { viewCount: 'asc' },
take: -2
})
);
// use a cursor to locate a page, note the cursor item is included
console.log('Find with cursor id=2, inclusive');
console.log(
await db.post.findMany({
orderBy: { id: 'asc' },
cursor: { id: 2 }
})
);
// exclude the cursor with `skip`
console.log('Find with cursor slug="post2", exclusive');
console.log(
await db.post.findMany({
orderBy: { id: 'asc' },
cursor: { id: 2 },
skip: 1
})
);
// cursor can contain multiple filters
console.log('Find with cursor id=2 && slug="post2"');
console.log(
await db.post.findMany({
orderBy: { id: 'asc' },
cursor: { id: 2, slug: 'post2' },
skip: 1
})
);
}
main();