Working with Read Operations
1. Finding Unique Record
const user = await prisma.user.findUnique({ where: { id: 1 } });
const byCompound = await prisma.userRole.findUnique({
where: { userId_roleId: { userId: 1, roleId: 2 } }
});
| Aspect | Detail |
| Where | Must be unique field or compound |
| Returns | Record or null |
2. Finding First Match
| Option | Use |
where | Arbitrary filter |
orderBy | Define "first" |
| Returns | Record or null |
3. Finding Multiple Records
const posts = await prisma.post.findMany({
where: { published: true },
orderBy: { createdAt: "desc" },
take: 20,
skip: 0
});
| Param | Detail |
where | Filter |
take / skip | Limit/offset |
cursor | Cursor-based pagination |
distinct | Distinct fields |
| Option | Notes |
include | Fetch entire related rows |
| Nested | Drill into relations |
| relationLoadStrategy | "join" | "query" (preview) |
5. Selecting Specific Fields
await prisma.user.findMany({
select: { id: true, email: true, posts: { select: { title: true } } }
});
| Tip | Detail |
| Bandwidth | Avoid SELECT * |
| Combine | Use nested select for relations |
6. Using findUniqueOrThrow Method
| Aspect | Detail |
| Behavior | Throws NotFoundError if no match |
| Error code | P2025 |
7. Using findFirstOrThrow Method
| Use | Detail |
| Non-unique filters | First match required |
| Throws | P2025 on miss |
8. Counting Records
const total = await prisma.post.count({ where: { published: true } });
| Variant | Use |
count() | Total rows |
count({ select: { id: true } }) | Per-field non-null counts |
9. Using Aggregations
const stats = await prisma.order.aggregate({
_sum: { total: true },
_avg: { total: true },
_count: { _all: true }
});
| Op | Result |
_sum/_avg/_min/_max | Numeric/DateTime fields |
_count | Row count |
10. Checking Record Existence
const exists = (await prisma.user.count({ where: { email } })) > 0;
| Approach | Detail |
| count | Fast for indexed fields |
| findUnique + null check | Fetches whole row (more cost) |