首页 / Prisma ORM 入门教程 / 过滤:where 与操作符全集

Prisma ORM 入门教程

过滤:where 与操作符全集

本教程共 54 篇 · 第 22 篇 · 更新于 2026-08-11 · 约 4 分钟阅读

where过滤操作符关系过滤JSON 过滤查询

本节目标:掌握 where 的全部操作符,学会组合条件、过滤关系与 JSON 字段。

第 19 章已经会用 where: { published: true } 做简单过滤。真实业务的条件复杂得多:范围、模糊、多条件组合、按关系过滤。这一章把操作符全集过一遍。

等值与简写

字段精确匹配有两种写法:

// 简写
await prisma.post.findMany({ where: { status: "PUBLISHED" } });

// 完整写法
await prisma.post.findMany({
  where: { status: { equals: "PUBLISHED" } },
});

简写内部就是 equals,两者完全等价。不想要某个值,用 not;但注意 not 不会返回该字段为 null 的记录,需要 null 时补一个 OR:

await prisma.user.findMany({
  where: {
    OR: [{ name: { not: "Eleanor" } }, { name: null }],
  },
});

列表与范围

值在不在一个集合里,用 in / notIn:

await prisma.user.findMany({
  where: { role: { in: ["ADMIN", "EDITOR"] } },
});

数值与日期的大小比较用 lt / lte / gt / gte,分别对应小于、小于等于、大于、大于等于:

await prisma.post.findMany({
  where: { likes: { gte: 100, lt: 1000 } },
});

日期直接传 Date 对象:

where: { createdAt: { gte: new Date("2026-01-01") } },

字符串匹配

contains 是子串匹配,startsWith、endsWith 管前缀后缀:

await prisma.user.findMany({
  where: { email: { endsWith: "prisma.io" } },
});

大小写不敏感加 mode:

await prisma.post.findMany({
  where: { title: { contains: "prisma", mode: "insensitive" } },
});
Note

mode: "insensitive" 只在 PostgreSQL 连接器上可用(MongoDB 也支持,但 v7 不支持 MongoDB,相关用法留 v6.19)。MySQL 靠数据库排序规则(collation)决定,SQLite 支持有限。

Tip

startsWith 能走普通索引,contains 相当于 %关键词%,用不上索引,表大了会慢。前缀搜索优先用 startsWith。

组合:AND / OR / NOT

同层的多个条件默认是 AND 关系,不用显式写。需要括号语义时再用操作符:

await prisma.post.findMany({
  where: {
    OR: [
      { title: { contains: "Prisma" } },
      { title: { contains: "数据库" } },
    ],
    NOT: { title: { contains: "SQL" } },
    published: true,
  },
});

AND 里的条件也可以写成数组,适合程序动态拼接过滤条件。

关系过滤

按关联数据过滤是 Prisma 的强项。一对多关系有三个操作符:

await prisma.user.findMany({
  where: {
    posts: {
      some: { published: true },     // 至少一篇已发布
      every: { likes: { lte: 50 } }, // 所有帖子点赞都不超过 50
      none: { views: { gt: 100 } },  // 没有帖子超过 100 次浏览
    },
  },
});

some 表示至少一条相关记录满足,none 表示一条都不满足,every 表示全部满足。注意 every 对没有帖子的用户也成立(空集满足所有条件),跟业务直觉可能相反。

一对多关系还可以传空对象判断有无:

// 至少有一篇帖子的用户
where: { posts: { some: {} } },
// 一篇帖子都没有的用户
where: { posts: { none: {} } },

一对一关系用 is / isNot,判断关系不存在直接传 null:

await prisma.post.findMany({
  where: {
    author: { isNot: { name: "Bob" }, is: { age: { gt: 40 } } },
  },
});

JSON 字段过滤

JSON 字段用 path 定位路径再比较。PostgreSQL 的 path 是数组,MySQL 是字符串:

// PostgreSQL
await prisma.user.findMany({
  where: {
    settings: {
      path: ["notifications", "email"],
      equals: true,
    },
  },
});

字符串与数组还有专门操作符:

// PG:settings.favorites.tags 数组包含 "prisma"
where: {
  settings: {
    path: ["favorites", "tags"],
    array_contains: ["prisma"],
  },
},
Note

PostgreSQL 的 JSON 过滤区分大小写,不支持 mode;且无法按「数组里对象的某个键」过滤(如 treats[*].name),这类查询只有 MySQL 支持。两种数据库的 path 写法不同(数组 vs $.a.b),跨库移植要留意。

参考来源

  • Prisma 官方文档:Filtering and sorting
  • Prisma 官方文档:Prisma Client API reference(Filter conditions and operators / Json filters)
  • Mapagam:Filtering Query Results
  • DevSheets:Advanced Querying & Filtering