Support multiple unique fields in dgraph GraphQL

Moved from GitHub dgraph/5232

Posted by sessionboy:

What you wanted to do

Expect team to provide support for multiple unique fields in dgraph GraphQL, this is a very common requirement, like this:

 type User {
    id: ID!
    name: String! @unique
    username: String! @unique
    phone_number: String! @unique
    email: String @unique
    ...
 }

The unique field is allowed to be empty, and no verification is performed when the value of the unique field is empty. For example email above.

Any external references to support your case

prisma provides a great implementation for this, which can be used as a reference.

5 Likes

MichaelJCompton commented :

Hi, thanks for the suggestion.

We’ll take this onboard as we look at GraphQL features. No commitment yet on what we’ll support, but it would be great to support composite keys as well as the kind of uniqueness described here.

2 Likes

sessionboy commented :

Thanks for team efforts, I look forward to it.

Any update on this?

1 Like

Hi @Wulfheart, this request is definitely in our roadmap and the team has plans to work on it. This can be seen in the docs too at the bottom of GraphQL docs. :slight_smile:

5 Likes

Hi. Nice to see this on the radar. I am interested in this as well. It would be great to have not just IDs but also composite unique constraints like unique (col1, col2) Thanks

3 Likes

Is there an ETA yet?

1 Like

Hi @vinniefg, thanks for showing interest in this feature.
Sorry, this won’t be part of the next 20.11 release. But this is definitely under consideration for later and maybe prioritized based on demands. I can’t give you any ETA though.
Thanks.

2 Likes

+1 on this feature. Hopefully this gets implemented by the team soon.

3 Likes

Also +1 on this feature. Feels like a basic thing to have.

1 Like

Hi, +1 for this feature.

Does the unique field will also support unique constraint based on the filtering on a given field ? For example, if we want to have unique label names per company, we could say

type Label {
  name: String! @unique(f: "company") 
  company:  String! @search
}
1 Like

Hi @dtrckd, as of now we are just allowing the @id field to be applied on multiple field in a type and every field with @id directive will be unique over the nodes of that type.
RFC: RFC: Allow multiple unique fields in graphql schema

1 Like

When you say “as of now,” what version of dgraph is “now?”

Hi @oising,

Welcome to Dgraph Community !!

Multiple ID fields feature is in planning stage and is not available in any Dgraph versions. The related RFC is RFC: Allow multiple unique fields in graphql schema .

The “as of now” refers to what is being considered in RFC and does not refer to any existing Dgraph version.

If you want to to know the latest version of Dgraph, it is 20.11 . You may find more details here, Release Notes v20.11.0 - Tenacious T'Challa .

1 Like

@rajas I just wanted to give an example of a perfect use case for this. While you are building graphql facets, there is a need for this in basic graphs.

Let’s say a user reviews a movie, there should be only one review:

Obviously, it would be better to have a unique restraint like in SQL:

ALTER TABLE `Rating` ADD UNIQUE `unique_index`(`user`, `movie`);

J

Hi @jdgamble555, support for multiple @id’s is already added in graphql and available in 21.03. In addition to that we also added some more features to @id fields like mutable and nullable @id fields which will be avaliable in 21.07. follow the below link for more details.
RFC: RFC: Allow multiple unique fields in graphql schema
PR: Feat(GraphQL): This PR allow multiple @id fields in a type. by JatinDevDG · Pull Request #7235 · dgraph-io/dgraph · GitHub

Hi @JatinDevDG.

I guess multiple @id nodes are the same thing as a unique restrain on two fields if you think about it.

Thanks, I didn’t realize that!

UPDATE 5/16/21:

What I was talking about here are composite id fields:

J

Hi @jdgamble555, multiple @id fields doesn’t guarantee unique constrain on a combination of two fields.
It just means that we can have multiple @id fields in a type. And every such field value will be unique across all the nodes of that type. But other @id fields or normal fields in a type can have that value. ​

Example :
type {
​t1: String @id
​t2: String @id
​t3: string
}

Below is the valid state according to @id rules but it doesn’t guarantee unique constraint on two fields.
node1:-
t1-“Alice”
t2-“Bob”

node2:-
t1-“Bob”
t2-“Alice”

We have a ticket for composite @id fields that will allow us to have a unique constraint on two or more fields and we will try to add it soon.
see this:
RFC: Allow multiple unique fields in graphql schema
Composite @id fields

2 Likes

Hi Jatin, I am a new user (2 days old), and was trying out dgraph.

on trying to insert duplicate values for fields which have ‘@id’ directive, i was expecting dgraph to throw error, but it seems it allowed it.

## curl -X POST localhost:8080/admin/schema --data-binary '@graph/schema.graphql'
type TransactionType {
    name: String! @id @search(by: [term])
    slug: String! @id
}

Note:

  1. noticed that in schema, the TransactionType.name field has index ‘hash’ as well as ‘term’. It seems ‘hash’ is added because it has constraint @id.
## curl -X POST 'http://localhost:8080/mutate?commitNow=true' --data-binary '@graph/insert.graphql' -H'Content-type: application/rdf'

{
 set {
        _:x  <dgraph.type> "TransactionType" .
  	_:x  <TransactionType.name> "Debit" .
	_:x <TransactionType.slug> "debit" .
	
	_:a <dgraph.type> "TransactionType" .
	_:a <TransactionType.name> "Debit" .
	_:a <TransactionType.slug> "debit" .
 }
}

Note:

  1. I was expecting this transaction to fail due to @id constraint on nodes TransactionType.name and TransactionType.slug

thanks
Rajat Jindal

Hi @rajatjindal , Welcome to the Dgraph community !!
@id is a graphql concept and works only in graphql layer. You posted a Graphql schema but the given mutation is of type DQL(Dgraph query language) and is on dgraph endpoint.
http://localhost:8080/query —DQL query endpoint
http://localhost:8080/mutate --DQL mutation endpoint

You need to use GraphQL mutation in order to use the @id feature and that will be on
http://localhost:8080/graphql --GraphQL query/mutation endpoint
see graphql docs for more details
https://dgraph.io/docs/graphql/