#Unique schema values
4 messages · Page 1 of 1 (latest)
Hi @icy hound. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Currently, Convex doesn't have built-in uniqueness constraints at the database level. However, there are two main approaches to implement unique values in your schema:
1. Manual Uniqueness Enforcement
You can enforce uniqueness by checking for existing values before inserting new documents:
// Define an index on the field you want to be unique
export default defineSchema({
users: defineTable({
email: v.string(),
// other fields...
}).index("by_email", ["email"]),
});
// In your mutation function
const existing = await ctx.db
.query("users")
.withIndex("by_email", (q) => q.eq("email", email))
.unique();
if (existing !== null) {
throw new Error(`Email ${email} is already in use`);
}
// If no existing document, proceed with insert
await ctx.db.insert("users", { email, /* other fields */ });
This approach works because Convex mutations run as transactions, so there's no race condition between checking for existence and inserting the new document Link to Discord thread.
2. Using Convex Ents (Recommended)
If you're looking for a more streamlined approach, you can use Convex Ents, which provides built-in support for unique fields:
// schema.ts
users: defineEnt({})
.field("email", { unique: true })
With this approach, the uniqueness check is performed automatically when writing to the table, without requiring additional code in your mutations Link to Stack article.
Note that when using unique fields with Convex Ents, you should be aware that uniqueness might behave differently with null/undefined values, and this has been noted as a potential feature request to improve Link to Discord thread.