How achieve one-to-one restraint?

  set {
    _:user <name> "foo" .
    _:user <name> "bar" .

as you see, all the “properties” in dgraph are edges, so I can add a same property twice, this is one-to-many, so how achieve one-to-one restraint?

I’d say triples. Edges are most likely used to exemplify a connection.

Yeah, but not for the same predicate/edge. In your example, “foo” would be overwritten by “bar”.

Something is wrong here, your RDF isn’t one-to-many. There’s no relation in your example.

Well, in the case you talking about an Edge. You would define it on your schema. Take this example below from the docs

friend: [uid] .
best_friend: uid .

Now the RDF

  set {
    _:user1 <name> "foo" .
    _:user1 <friend> _:user2 .
    _:user1 <friend> _:user3 .

    _:user2 <name> "bar" .
    _:user2 <friend> _:user4 .
    _:user2 <best_friend> _:user5 .

So, only “best_friend” edge is “one to one”.

If you are confused about DQL syntax. Please take our tour. A Tour of Dgraph

@MichelDiz clear enough, thanks! well in the tour, most is about “how to”, is there some place to explain the basic principles of dgraph ?

I thought that the tour covers that. What do you need? What still not clear for you? I might bring something or create something.

@MichelDiz nodes, edges, triples, and the relationship of them. for example:

  set {
    _:user1 <name> "foo" .
    _:user1 <friend> _user2 .

well “name” and “friend” are edges, user1 and user2 are nodes ,right? like that, “foo” is a node too? what kind of node it is?

to make sense to me, I divide nodes into two kinds, Entity nodes, has uid, like user1 user2; Value nodes, just has an value, like ‘foo’. am I right?

_:user1 and _:user2 are blank node references. They will create a new node for each unique blank node in a mutation.

<name> and <friend> are both predicates in the Subject-Predicate-Object (SPO) triple.

It is common to call the friend predicate an edge because it connects two nodes

"foo" is not commonly called a node, but a string value.

It is uncommon to call name an edge because it is not joining two nodes.

Fundamentally an entity node and value node is a correct understanding, but that is not the common lingo here.

Here are the main terms:

Here are the relevant sections of the tour to answer your questions.

@verneleem so if “foo” can be treated as a node, what exactly happened in the dgrah? for example:

  set {
    _:user1 <name> "foo" .
    _:user2 <name> "foo" .

how many “foo” will be created in dgraph finally ?

But “foo” is not being treated as a node in the context you are using. It is a value. Your example creates a node for user one and a node for user two, each having their own “foo” value. If you update one of the “foo” to “bar” it does not alter the other “foo”

@verneleem understand, just like value type and reference type in programming languages,thanks .

@verneleem I think “foo” is node too,consider this:

type User {

type Dog {

name string @index(term) .

I think both User and Dog’s name are indexed, and func:has(name) will query them all . even it can be deleted from the edge, it still behave as node in someway .

Well, this is true, but the reasoning is deeper. It is not indexing in a relational context like you are probably thinking. Indexing is done by predicate, not by type. So since the index is on the predicate name that is the predicate that gets indexed no matter what types it may appear in.

Again, this behaviour is based upon the predicate not the type as you might be thinking from a rdbms background. This has function is literally asking the database for all of the nodes that have the name predicate no matter the type. If you want to add a type restriction then you would need to add @filter(type(User)).

Looking at the Subject-Predicate-Object triple format we can better understand this behavior.

some data:

_:user1 <dgraph.type> "User" .
_:user1 <name> "Alan Smithee" .
_:user2 <dgraph.type> "User" .
_:user2 <name> "David Agnew" .
_:dog1 <dgraph.type> "Dog" .
_:dog1 <name> "Bella" .
_:dog2 <dgraph.type> "Dog" .
_:dog2 <name> "Luna" .

With this data and your schema above, this would index every triple that uses the <name> predicate.
When queried with has(name) it will return every node that has the <name> predicate. Indexes are never type specific.

If you need type specific indexes then you can do this like the GraphQL schema produces. Consider the use case where you add a description predicate to both User and Dog, and you want to only index User description with term and only index Dog description with hash. To do this you would need to separate the predicates. The GraphQL endpoint schema, does this natively with Dgraph because it produces a different predicate for each type such that the schema would look like:

type User {

type Dog {

User.descripton string @index(term)
Dog.description string @index(hash)

With a schema like this, when using the has function, the results will be somewhat normalized to only results that are most likely of the type. I saw “somewhat” and “most likely” because it is still possible to create a node that has the User.description and doesn’t have a type which would be returned in the results for has(User.description) but not the results for type(User)

From the docs:

data node: A basic unit of data representing an entity in a graph database. Nodes are connected by edges and have predicates (or fields ) that contain node data.

Everything can be seen as a graph all the way down to the atomic level. This may lead to the comprehension that "foo" is a node, but it is not a node in the way that Dgraph describes data nodes. Even though "foo" is a basic unit representing a value, it cannot be connected to multiple nodes through edges. It might appear to be able to connect multiple nodes through edges with the function eq(name,"foo") will get a list of all nodes that have the predicate name that is equal to foo, but notice that this is not getting a single node by the value “foo” and finding all of the edges to other nodes.

Let me know if you have any additional questions.

“predicate” is also called “edge” sometimes in the doc, that make me think that dgraph is totally atomic .
now I wonder how the scalar list type is treated in dgraph, is it a value type? can I set it’s value in this way: set {_:blog <tags> ["gql", "apollo", "dgraph"]}?

The syntax for List Type in RDF is multiple RDF lines with the same identifier.

_:blog <tags> "gql"     .
_:blog <tags> "apollo"  .
_:blog <tags> "dgraph"  .

This will be converted to a List internally. That’s how RDF works.

This white paper may help with some of the deeper understanding into Dgraph

@verneleem white paper helps much! thanks .