Hmm I see, that is really too bad as having uniqueness be isolated to only a single field a significant drawback for using Dgraph. It is really needed in certain situations wherein you cant just “create” a composite key under one field because you do not control the querying (The queries are made by the end user).
So, I disagree.
I think you’re confusing indexes and constraints in this situation.
What we want is to put @id on multiple fields at the same time. This is equivalent to a unique constraint on multiple fields (or primary key) in SQL. The $VARIABLE1__$VARIABLE2 is how noSQL handles this.
From my understanding, the @id directive indexes on the GraphQL level as middleware, not in the database itself. Because of that, it does not matter where and how the shards are stored in Dgraph, and ultimately in badger.
I do believe that in order for this GraphQl to be complete one day, @id on multiple fields should be on that feature list. However, it is not at the top of the list, because we just need to think more in Graph terms to remodel the data.
I do agree with you on this.
That being said, there are two work arounds currently:
type node {
id: String! @id
version: String! @id
}
This could be translated to:
type node {
id: String! @id
version: [String!]
}
What we’re saying is that we want to require uniqueness for id and version together. Done.
The other work around of course is to block the ADD / UPDATE mutations, and use a Custom Lambda Mutation for both to enforce it.
EDIT: I would say the better workaround would be to allow @auth rules to use database values. That way you can have a noSQL sort of workaround where you enforce $fieldC = $fieldA + __ + $fieldB. Just a thought.
J
If i’m not wrong @Tyler_D you can already use @id in two or more fields.
As @jdgamble555 said i think it’s only middleware that ensures uniqueness (thats why @unique would make more sense here and this is another reason )
As it ensures uniqueness, It also grants the power to filter nodes using it, and I guess that’s the reason behind calling it @id. But I think it is confusing
But coming back to the main problem, we need uniqueness in the composition of those two unique values. And indeed, @auth rules that read current values in DB could at least impede the creation of a node if $fieldA + __ + $fieldB already exists in the DB. That would do a nice workaround to ensure uniqueness on creation.
we would still need pre-hooks in order to auto-calculate those composite-index as the combination, instead of forcing the graphql client to add them manually tho.
@loic Yes you can use more than 1 @id field but they all have to be individually unique. What I need is a composite primary key (where the 2 @id fields together define uniqueness).
yep yep i know, i have the same need for another use case @id as the combination of two things (composite index)
I still think this could be done solely on the GraphQl middlewhere layer, where we could perhaps have something like:
type Node @id(person, job) {
id: ID!
person: Person!
job: Job!
...
}
query {
getNode(person: '0x1', job: '0x2') {
...
}
}
maybe internally it creates an _id field for the composite index, and would work the same as expected.
I am not sure if that would be less work then allowing an auth rule to do this.
You would need pre-hooks or the ability to create the @auth rule, but not necessarily both. With prehooks, you don’t need the @auth rule at all.
J
I think the ideal case would be having both your @id middleware which seems an amazing idea to describe composite ids, and @unique to ensure uniqueness for certain fields and being able to filter by those, so something like this could be intuitive and powerful:
type Application @id(person, job) {
id: ID!
person: Person!
job: Job!
applicationCode: String! @Unique
...
}
And yes! I wish pre-hooks are a thing soon!