Skip to main content

Queries & operators

where is a Mongo/Prisma-style filter. For typed collections, keys are checked against your type (dot-paths allowed).

Comparison

where: { age: { equals: 30 } } // or shorthand: { age: 30 }
where: { age: { gt: 18, lte: 65 } }
where: { role: { in: ["admin", "editor"] } }
where: { role: { notIn: ["guest"] } }
where: { name: { not: "Ali" } }

Strings

where: { name: { contains: "li" } } // case-sensitive substring
where: { name: { startsWith: "A" } }
where: { name: { endsWith: "i" } }
where: { name: { contains: "ALI", mode: "insensitive" } } // case-insensitive

Regex

JavaScript RegExp semantics — works identically on every driver, including the browser:

where: { email: { regex: "@acme\\.com$" } }
where: { name: { regex: "^al", mode: "insensitive" } } // or a literal: { regex: /^al/i }

Arrays

where: { tags: { has: "admin" } } // element membership
where: { scores: { elemMatch: { gte: 90 } } } // any scalar element matches
where: { items: { elemMatch: { sku: "A", qty: { gte: 2 } } } } // any object element ($elemMatch)

Existence & nesting

where: { phone: { exists: true } }
where: { "address.city": { equals: "Riyadh" } } // dot-path

Logical

where: { AND: [{ age: { gte: 18 } }, { active: true }] }
where: { OR: [{ role: "admin" }, { role: "editor" }] }
where: { NOT: { role: "guest" } }
where: { role: "admin", age: { gt: 30 } } // multiple fields ⇒ implicit AND

Ordering, pagination, joins

await orders.findMany({
where: { status: "open" },
orderBy: [{ priority: "desc" }, { created_at: "asc" }],
take: 50,
skip: 100,
// left-join another collection ($lookup); unwind: true flattens ($unwind)
lookup: { from: "users", localField: "userId", foreignField: "_id", as: "user" },
});

lookup runs as two queries (no N+1) in both document and structured modes.