How to design edges?


Hey, sorry for this broad question but it comes with a concrete example :slight_smile:

I’m struggling to design my schemas on my project regarding edges. I come from orientDB where edges can be defined as a simple table. I’m trying to use edges the same way, replacing table fields by facets, but I’m facing limitations.
Also, my project is in Go, and it’s possible that some of these limitations I’m facing actually come from the dgo sdk, and not dgraph itself.

Here comes the concrete example:
In this DB we have Person nodes let’s say P and Company nodes, C.
P can be linked to other P (colleagues, friend, lover…)
P can be linked to C (director, employee…)

Solution 1

My very first idea was to have two types of edges, PP to link a P to another P, and PC, to link a P to a C. They would have a facet to describe the nature of the relationship, such as relationship=colleague.

I found facets limiting here as for instance I couldn’t figure out how to delete an edge based on a specific facet. This does not work for a delete action:

  "uid": "0x1",
  "PP": {
    "uid": "0x2",
    "PP|relationship": "colleague"

Another big problem with that solution was that it seems it’s not possible to have more than one edge of the same type linking 2 nodes. So if 2 P are both colleagues and lovers, I’m doomed. (or can facets be array?)

After more thoughts, I started to think it was wrong to define edges that way, as in many dgraph example you can see that Alice and Bob are linked by a friend edge, and not by a PersonToPerson edge with a relationship=friend facet.

So then came the solution 2

Solution 2

Do not define types for edges and let the relationship described previously be the edge type.
That’s interesting but does not seem to be dynamic enough for my use case (I don’t know in advance all the type of relationship that will end up in the database)
Then I faced the same error as already reported here Find all inbound outbound edges
This thread sums up all the issues I faced trying to implement my edges this way, but I’ll add one more thing:
When expanding data, the returned JSON is of form:

  "data": {
    "get": [
        "PP": [
            "uid": "0xc355",
            "uid": "0xea61",

This JSON format forces you to know in advance the type of edges you’ll be unmarshaling.

Could I get some enlightment regarding best practices here?

(Michel Conrado) #2

It can’t happen like this. Deletion operation don’t bases on the format of the JSON or RDF. You can only delete something by UID, by relation (knowing two UIDs), SPO or “S P * and S * *” star deletion. Dgraph will not take into account the fact that you use Facets in a delete operation.

Instead you could use an upsert procedure. And rely on Facets if you really need to do it.

BTW Facets are not edges, they are information you can add between edges. Also they’re not first - class citizen.

Okay, why not a simple format like below?

  "uid": "0x1",
  "name": "Sandro Jose",
  "age": "32",
  "colleague": {
    "uid": "0x2"
  "lover": {
    "uid": "0x2"
  "friend": [{"uid": "0x2"},{"uid": "0x13"},{"uid": "0x12"},{"uid": "0x22"}]