6.1 关键概念
- 过滤器操作符(filter operator)
- where 里的比较条件,如
equals、not、in、gt/gte/lt/lte、contains、startsWith、mode: "insensitive"(不区分大小写)。 - 逻辑组合 AND/OR/NOT
- where 顶层可用
AND、OR、NOT数组组合多个条件,实现复杂布尔逻辑。 - 游标分页(cursor pagination)
- 用
cursor+take+skip基于上一页最后一条记录定位下一页,比 offset 分页在大数据集上更稳更快。 - aggregate
- 聚合查询:
_count、_sum、_avg、_min、_max,一次算出统计值。 - groupBy
- 按字段分组并对每组做聚合,配合
having过滤分组结果,等价 SQL 的 GROUP BY。 - 关系过滤 some/every/none
- 对一对多关系做条件:
some(存在满足的子记录)、every(全部满足)、none(没有满足的)。一对一/多对一用is/isNot。 - 嵌套写入(nested writes)
- 在一次 create/update 中同时操作关联记录:
create、connect、connectOrCreate、update、upsert、disconnect、set、delete,Prisma 自动包进事务。
6.2 where 过滤器
const rows = await prisma.user.findMany({
where: {
AND: [
{ age: { gte: 18, lt: 60 } },
{ email: { endsWith: "@example.com" } },
],
OR: [
{ name: { contains: "ali", mode: "insensitive" } },
{ role: { in: ["ADMIN", "EDITOR"] } },
],
NOT: { name: null },
},
});
6.3 排序与分页
// offset 分页
await prisma.post.findMany({
orderBy: [{ published: "desc" }, { createdAt: "desc" }],
take: 20,
skip: 40, // 第 3 页
});
// 游标分页(大数据集推荐)
const page = await prisma.post.findMany({
take: 20,
skip: 1, // 跳过游标本身
cursor: { id: lastId },
orderBy: { id: "asc" },
});
6.4 聚合 aggregate
const stats = await prisma.order.aggregate({
where: { status: "PAID" },
_count: true,
_sum: { amount: true },
_avg: { amount: true },
});
// { _count: 120, _sum: { amount: 98000 }, _avg: { amount: 816.6 } }
// 单独计数
const total = await prisma.user.count({ where: { role: "USER" } });
6.5 分组 groupBy
const byStatus = await prisma.order.groupBy({
by: ["status"],
_count: { _all: true },
_sum: { amount: true },
having: { amount: { _sum: { gt: 1000 } } },
orderBy: { _sum: { amount: "desc" } },
});
6.6 关系条件过滤
// 至少发过一篇已发布文章的用户
await prisma.user.findMany({
where: { posts: { some: { published: true } } },
});
// 所有文章都已发布 / 一篇都没发布
await prisma.user.findMany({
where: {
AND: [
{ posts: { every: { published: true } } },
{ posts: { none: { flagged: true } } },
],
},
});
// 关系计数 _count
await prisma.user.findMany({
include: { _count: { select: { posts: true } } },
});
6.7 嵌套写入
await prisma.user.update({
where: { id: 1 },
data: {
posts: {
create: { title: "New" }, // 新建关联
connect: { id: 99 }, // 关联已有
connectOrCreate: { // 有则连,无则建
where: { slug: "prisma" },
create: { title: "Prisma", slug: "prisma" },
},
updateMany: { where: { published: false }, data: { archived: true } },
deleteMany: { where: { flagged: true } },
},
},
});
嵌套写入自动进事务
一个嵌套写入内的多步操作是原子的——全部成功或全部回滚,无需手动包 $transaction。多对多关系还可用 set 整体替换关联集合。
警惕 N+1
循环里逐条查关系会产生大量往返(N+1 查询)。用 include/嵌套 select 一次带出关系,或用 findMany+in 批量取,避免遍历中发查询。第 10 章细讲。
6.8 小结与下一步
- where 支持丰富操作符与
AND/OR/NOT组合;大数据集用游标分页。 aggregate/count/groupBy做统计;关系用some/every/none过滤、_count计数。- 嵌套写入一次操作关联并自动进事务。
- 下一章讲 事务与原始查询——$transaction 与 $queryRaw。