Dgraph for rdfs domain and range?

Hi,
Newbie here. We have a project using Dgraph, and the schema is written in GraphQL± (I believe).

Is there a way to incorporate the concepts of RDF domain and range, into our schema? If there is a Dgraph doc on this, that would be fine to link to. I did try to search for one, and search the forum here, but could not find anything.

Thank you!

Do you mean, that you want to specify domain and range to the values in the RDFs?

Example: If _:Leka <age> 25, then you want to impose a constraint on what values of ages are admissible?

Yes, that’s the core concept I was getting at. In both directions (domain/range) I just know that rdfs:domain and rdfs:range is a thing, but I don’t necessarily want to use rdf. Is there something (close to) “equivalent” to that in graphql± / Dgraph?

Thank you!

EDIT: To expand a bit, is there something that can be done in the schema (graphQL±) to enforce such constraints? I’m not 100% sure if that question even makes sense. But basically like you posed it: when someone goes to input data into our schema, how do we define in the schema to constrain the the types that the user is trying to link, to not be the incorrect type, in the sense of rdfs:domain and rdfs:range ?

Let’s do a toy example.

Schema:

type Person {
name
age
friend
owns_pet
owns_vehicle
}

type Dog {
name
breed
}

type Cat {
name
breed
}

type Car {
name
make
}

name: string @index(term) .
age: int .
friend: [uid] .
owns_pet: [uid] .
owns_vehicle: [uid] .
breed: string .
make: string .

Data example:

{
set {
_:michael “Michael” .
_:michael <dgraph.type> “Person” .
_:michael “39” .
_:michael <owns_pet> _:bark .
_:michael _:luke .

_:luke <name> "Luke" .
_:luke <dgraph.type> "Person" .
_:luke <age> "77" .
_:luke <owns_pet> _:meow .
_:luke <friend> _:Michael .

_:bark <name> "Bark" .
_:bark <dgraph.type> "Dog" .
_:bark <breed> "Great Dane" .

_:meow <name> "Meow" .
_:meow <dgraph.type> "Cat" .
_:meow <breed> "Siamese" .

}
}

I think in rdfs you could say something like, owns_pet has range of “Dog”,“Cat” ? But clearly “Car” doesn’t fit into that?

2 Likes

@leka0024 That’s an interesting use-case. I haven’t encountered this before though, but at some place we do check the validity of schema with respect to data in field I suppose. What I mean is if you schema specifies string but you pass in an integer then either it type-casts or throws. Let me look around and get back to you. Thanks!

Also Welcome to Dgraph! :slight_smile: :partying_face:

Thanks @Anurag

Please see this link: https://www.w3.org/TR/owl-ref/#domain-def

in particular, for domain it notes (and gives an example):

An rdfs:domain axiom asserts that the subjects of such property statements must belong to the class extension of the indicated class description.

similar for range (right beneath).

Really what we want, like in the toy example, is to prevent someone else, who is putting in data to the ontology schema to create an instance, from incorrectly linking the various types of sub-classes/objects. It shouldn’t be allowed to link a Car object to Michael, via the owns_pet property. That type of thing.

Does Dgraph have this type of constraining ability? Thank you!

Dgraph, can’t do that.

The only similar constraints Dgraph has is https://dgraph.io/docs/deploy/#restricting-mutation-operations

I think this ticket https://github.com/dgraph-io/dgraph/issues/5624 could implement this idea of constraint in edges by type. I gonna formulate this on the ticket.

Thank you @MichelDiz

Any idea how quickly edge constraints by type could get implemented? Not until the next version dot release? End of summer maybe?

I think it may take a while, as the Dev Core team is very busy with several tickets. I think the implementation would look very similar to https://github.com/dgraph-io/dgraph/pull/2863

1 Like

I think another way to implement edge constraint would be to extend types package in dgraph. See here where we impose restrictions on primitive types while converting from string to respective types mentioned in the schema. Imposing a condition which checks for dgraph.type is a possible solution.

Thanks!

Thanks for the comment @Anurag. Was that directed at me, as something I should try, or is that directed to future development efforts?

@leka0024 I wanted to put on note the research I did around adding such constraints. You are welcome to take a stab at it, though I feel it would require significant time investment if not familiar with the dgraph code base already.

Thanks!

1 Like

@Anurag Thanks for the clarification. I don’t have the time or skill necessary to help with the development.

FWIW, I think these edge type constrains would be hugely useful for ontology designers. I’m surprised no one has asked for this before. Please consider if you can prioritize this feature development, if it doesn’t eat up too much resources. Thank you!

No worries! Thanks for bringing this issue to light. @MichelDiz has already created a ticket. We will update you on this thread once we get time to work on it. Feel free to raise more questions and discussions around here.

Thanks!

I’m pretty interested on ontology users using Dgraph to do so. Whenever you can share your experiences with Dgraph + ontology. There are some users who have given up because we don’t have a specific standard/tips for people on how to use ontologies in Dgraph. But there are definitely people in the community who are interested, they just don’t have the time.

1 Like

After digging more around dgraph, I think you could implement these constraint using GraphQL schema instead of GraphQL±

For your particular case you could do something like this:

interface Animal {
  type: String 
}

type Dog implements Animal {
  name: String
  breed: String
}

type Cat implements Animal {
  name: String
  breed: String
}

type Person {
name: String
age: Int 
owns_pet: Animal
owns_vehicle: Vehicle
}

This will ensure that owns_pet gets mapped only to Animal. Does this work for you?

Thanks!

Hi @Anurag,

When I try to upload this schema, I get the following error message:

Processing schema file "toy_schema_QL"
Error while processing schema file "toy_schema_QL": rpc error: code = Unknown desc = line 1 column 10: Missing colon

The error seems to follow the interface definition.

Also, do I not need to define each property below the type definitions, like before?

name: string @index(term) .
age: int .
friend: [uid] .
owns_pet: [uid] .
owns_vehicle: [uid] .
breed: string .
make: string .

One more question: would the interface and type ___ implements ___ be able to be “stacked”, implementing a hierarchy of object/class and sub-object/sub-class? Like for example, top level class of “Transportation”, then a sub-class of “Vehicle”, then sub-classes “Car” and “Truck” ?

Thank you!

Hi @leka0024 updates below.

Are you uploading the schema via GraphQL client also which endpoint are you hitting? Ratel would not work anymore. You should submit the schema to localhost:8080/admin/schema. See step 2 here. Queries and Mutations should go to localhost:8080/graphql

No, since earlier you were defining the types in GraphQL±. Now you should follow GraphQL syntax

No, spec doesn’t allow stacking.

@MichelDiz – Thank you for corrections! :slight_smile:

Thanks

1 Like

Hi again @Anurag , thank you for the very prompt reply!

Unless there is a GUI for uploading (like Ratel), or it can follow the dgraph live command somehow, then I don’t know how to upload the schema. When I tried to navigate to localhost:8000/graphql it shows (Asset not found for path graphql) . EDIT: and same (Asset not found for path admin/schema)

I’m trying to think if this will still even work for us.

Say we have an object like “Travel Itinerary”. It needs a transportation object linked to it. Within that object, it needs option for vehicle (like someone driving something themselves) or riding (like someone paying for a ride on some type). Then each of these can be linked to sub-objects, eg Car, Truck, Van in the first, and Bus, Plane, Boat, etc. in the second.

Does this make sense? And we need to prevent someone linking some other type of object when inputting data, like a warehouse location.

Hi @leka0024 can you check once with localhost:8080/graphql. I wrote the wrong the default port (edited now).