Here is the trick while I am trying to design the schema of my project, to simplify the question, let’s say I have 3 types of node: person, dog, and cat, and I want to use the love edge to present a person “love” dog and cat. How to describe this in the Dgraph? I was trying to use GraphQL to define this schema, then I found myself in trouble. Any suggestion will be appreciated.
type Person {
first_name: String! @search(by: [exact])
last_name: String! @search(by: [exact])
love: dog?cat?
}
Post the following schema. We introduce a union type pet that can refer to either a Dog or Cat. We set the type of love to pet
type Person {
id: ID!
first_name: String! @search(by: [exact])
last_name: String! @search(by: [exact])
love: pet
}
type Dog {
breed: String! @id @search(by: [hash])
}
type Cat {
color: String! @id @search(by: [hash])
}
union pet = Dog | Cat
Let’s post some pets. I use the graphql playground and use the following mutations and queries.
Finally, we can query using fragments. These are the lines with `… on Dog…which helps the query language understand that thebreedbelongs to aDog, and colorto aCat``.
query{
queryPerson(first: 5){
first_name
love {... on Dog {
breed
}
... on Cat {
color
}
}
}
}
Thanks for that! It works like a charm. here is another question, if I want to have the reverse edge “loved_by” from Dog and Cat, how should I state in GraphQL?
type Dog {
breed: String! @id @search(by: [hash])
loved_by: [Person] @hasInverse(field: love)
}
this throws an error on me:
Field loved_by: inverse field love doesn't exist for type Person
As per documentation, union types cannot scalars and interfaces. So I had to create a wrapper type APet.
Use this schema to wrap the pet and add the inverse link as below.
type Person {
id: ID!
first_name: String! @search(by: [exact])
last_name: String! @search(by: [exact])
love: APet @hasInverse(field: lovedBy)
}
type APet{
lovedBy: Person
pet: pet
}
type Dog {
breed: String! @id @search(by: [hash])
}
type Cat {
color: String! @id @search(by: [hash])
}
union pet = Dog | Cat
Yes, you are right, it’s just my IDE complained about it, the command runs through, thanks.
But a strange thing happened, it does not add reverse to the predicate “love” automatically.
type Person {
id: ID!
first_name: String! @search(by: [exact])
last_name: String! @search(by: [exact])
love: APet @hasInverse(field: lovedBy)
}
type APet{
lovedBy: Person
pet: pet
}
type Dog {
breed: String! @id @search(by: [hash])
}
type Cat {
color: String! @id @search(by: [hash])
}
union pet = Dog | Cat