Deleting edges

I am trying to better understand delete mutations, specifically when deleting edges.

Using the following example schema and data:

type Person {
  first_name
  last_name
  has_spaceships
}
type Spaceship {
  ship_name
  is_owned_by
}
is_owned_by: uid @reverse .
has_spaceships: [uid] .
{
    set {
        _:Person <first_name> "Han" .
        _:Person <last_name> "Solo" .
        _:Person <dgraph.type> "Person" .
        _:Person <has_spaceships> _:Spaceship .

        _:Spaceship <is_owned_by> _:Person .
        _:Spaceship <ship_name> "Falcon" .
        _:Spaceship <dgraph.type> "Spaceship" .
    }
}

I can run the following Person query:

{
    query(func: type("Person")) {
        uid
        first_name
        last_name
        dgraph.type
        has_spaceship: ~is_owned_by {
            uid
            ship_name
            dgraph.type
        }
    }
}

This will show me Han (0x1) and an edge connection to his spaceship Falcon (0x2).

I can run this Spaceship query:

{
    query(func: type("Spaceship")) {
        uid
        ship_name
        dgraph.type
        is_owned_by {
            uid
            first_name
            dgraph.type
        }
    }
}

And that will show me the Falcon spaceship and an edge connection to the person Han.

Now if I delete Han, using S * *:

{
    delete {
        <0x1> * * .
    }
}

Repeating the Person query shows that all the predicates of 0x1 (“Han”) are gone, and the edge still exists.

uid "0x1"
  has_spaceship {
      uid         "0x2"
      ship_name   "Falcon"
      dgraph.type ["Spaceship"]
  }

If I reset all the data and instead of deleting the Person node, I instead delete the Spaceship node using S * *:

{
    delete {
        <0x2> * * .
    }
}

I can run the Person query and the edge will be gone. And of course I can run the Spaceship query and the Falcon node will be gone.

Question

I assume that the edge was only deleted when I deleted the Spaceship node because of the direction of the edge. The edge was a one-way relation from the Spaceship to the Person, not from the Person to the Spaceship. Is my assumption correct?

delete {
        <0x1> * * .
    }

Instructs Dgraph to delete every predicate it knows about node 0zx01.
The way it is done is to check ‘dgraph.type’ value for 0x01, which is ‘Person’. Then find the list of potential predicates using the type system.
It will find first_name, last_name, and has_spaceships and so will delete those predicates for this node.
As you saw it will not delete the predicate “is_owned_by” which is by the way on node 0x02.

GraphQL and DQL schemas - GraphQL dql provides info about the DQL Type system,
You can declare the reverse in Person using the angle bracket notation

type Person {
  <~is_owned_by>
}

In fact in your schema you declared a predicate has_spaceships but you can use directly ~is_owned_by, which you do in the query has_spaceship: ~is_owned_by

Declaring <~is_owned_by> in the Person type will make expand(all) and delete work.

1 Like