citrus
citrus•2mo ago

Just wondering if there's some kind of

Just wondering if there's some kind of way to db.insert() uniquely ? So, the table would have unique docs & if already exist, return an error ?
16 Replies
Hmza
Hmza•2mo ago
unique based on all fields or a single field?
citrus
citrusOP•2mo ago
on all fields. Basically, it's a relationship table with fields userId & ideaId. I think I'm not saying it correctly, sorry. So there should be only one doc with same userId & ideaId
erquhart
erquhart•2mo ago
You have to query to check for an existing doc that matches first. 1. Make an index that includes all fields that must be unique 2. Query with that index, use .unique() to collect 0 or 1 results, will throw if more 3. If there's no result, run your insert
citrus
citrusOP•2mo ago
Thank you If you could help me on how to index, please. Thank you interested: defineTable({ userId: v.id("users"), ideaId: v.id("ideas"), }).index("by_ideaId_userId", ["ideaId", "userId"]), I followed your step 1 & changed from 2 invidual index to this. However, there are places where I need to get all users for a certain idea or get all ideas for a certain user. So, how should I form my schema that helps me with both queries (& ensure unique docs as well) ?
erquhart
erquhart•2mo ago
You would add additional indexes, one for each field:
interested: defineTable({
userId: v.id("users"),
ideaId: v.id("ideas"),
})
.index("by_ideaId_userId", ["ideaId", "userId"])
.index("by_ideaId", ["ideaId"])
.index("by_userId", ["userId"])
interested: defineTable({
userId: v.id("users"),
ideaId: v.id("ideas"),
})
.index("by_ideaId_userId", ["ideaId", "userId"])
.index("by_ideaId", ["ideaId"])
.index("by_userId", ["userId"])
Use the ideaId index to query users for an ideaId, and vice versa
citrus
citrusOP•2mo ago
ohh, I see. I thought maybe that was not best practice. Thank you 🌼
erquhart
erquhart•2mo ago
One of the best and most disorienting things about Convex is how often the obvious, simple approach is also the ideal approach.
citrus
citrusOP•2mo ago
I 100% agree. having superr fun with convex
igor9silva
igor9silva•2mo ago
I like to imagine DB indexes as book indexes they take a little space (a few pages) and add extra work each time there is a mutation, as those indexes have to be up-to-date but when looking for an info, they'll help A LOT about having multiple indexes, you're paying that price a few times which, for most use cases, is completely fine however, there is one little "trick" - I don't think you need
.index("by_ideaId_userId", ["ideaId", "userId"])
.index("by_ideaId", ["ideaId"])
.index("by_userId", ["userId"])
.index("by_ideaId_userId", ["ideaId", "userId"])
.index("by_ideaId", ["ideaId"])
.index("by_userId", ["userId"])
but only
.index("by_ideaId_userId", ["ideaId", "userId"])
.index("by_userId", ["userId"])
.index("by_ideaId_userId", ["ideaId", "userId"])
.index("by_userId", ["userId"])
since "by_ideaId_userId" is already sorted by ideaId the "book index" would look something like - idea 1 - user 1 - user 2 - user 3 - idea 2 - user 1 - user 6 so the DB can properly sorte by ideaId only (but not from userId only, hence the 2nd index)
igor9silva
igor9silva•2mo ago
here is a real use-case I have
No description
No description
igor9silva
igor9silva•2mo ago
conceptually it's fine, but I don't really know if there is any Convex-specific issue with that approach
igor9silva
igor9silva•2mo ago
note that types work flawlessly it wont even allow me to use kind as the first index.eq()
No description
igor9silva
igor9silva•2mo ago
and will only allow kind on the second one, but not mandatory
No description
igor9silva
igor9silva•2mo ago
No description
erquhart
erquhart•2mo ago
That does work, but keep in mind the results will be ordered by the unused index(es), and then lastly by creation date, which may not be expected.
citrus
citrusOP•2mo ago
Thank you for the explanation. I think you're right, I don't need the "by_ideaId" index. I was actually trying out getManyFrom() from convex-helpers & when I use the "by_ideaId_userId", it requires ideaId & userId as arguments.
this approach withIndex works perfectly fine. maybe I'm not using them properly

Did you find this page helpful?