How to delete a node

Hi,

I have the following schema:

<ApiKeySet.title>: string .
<ApiKeySet.access_key>: string @index(hash) @upsert .
<ApiKeySet.secret_key>: password .
<ApiKeySet.last_used>: datetime .
<ApiKeySet.created_at>: datetime .
<User.api_key_sets>: uid @reverse .

type <ApiKeySet> {
	ApiKeySet.title
	ApiKeySet.access_key
	ApiKeySet.secret_key
	ApiKeySet.last_used
	ApiKeySet.created_at
}
type <User> {
	User.api_key_sets
}

I insert a node of API key set and set an existing user as ist owner by using the User.api_key_sets predicate
Then when I try to delete this node with S * * it deletes all of its data but it doesn’t remove it from the user node and I left with a ghost node:

Deleting the node from the user doesn’t delete the node itself also…

What should I do?

Does ApiKeySet and User has <dgraph.type> "User" OR "ApiKeySet"?

Yes

_:or <dgraph.type> "User" .
_:or <User.api_key_sets> _:aks1 .


_:aks1 <dgraph.type> "ApiKeySet" .
_:aks1 <ApiKeySet.title> "orkenus" .
_:aks1 <ApiKeySet.access_key> "K4CkitlTzjT50cyt4RJ9" .
_:aks1 <ApiKeySet.secret_key> "?J&cOymum8DToZfnX%3LA)s_6O\\A#:BWQ/>" .
_:aks1 <ApiKeySet.created_at> "2020-11-26T16:31:45.664119" .

Pls, share the delete operation you are doing.

assuming this is the id of the node of the api key set 0x24a1a

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

So, are you talking about the 0x24a19? are you using reverse index?

So, are you talking about the 0x24a19
Yes, the last one was just an example…

are you using reverse index?
Yes you can see the predicates above <User.api_key_sets> has the @reverse directive

You should try something like this

upsert {
  query {
    v as var(func: uid(0x24a1a)){
     incoming as <~User.api_key_sets>
     }
  }

  mutation {
    delete {
      uid(v) * * .
      uid(incoming) <User.api_key_sets> uid(v) .
    }
  }
}

That works yet it make things much more complicated
Is there any other way?

Yes and no, in the case you don’t explicitly state the entities Dgraph should “infer” all incoming edges and that would be a bit expensive to built in the delete operation - and over time a LOT expensive. The upsert solves this as I’ve shown.

But, in other cases, if you know both entities. You can do like this.

{
  delete {
    <0x24a1a> * * .
    <0x24a0a> <User.api_key_sets> <0x24a1a> .
  }
}

Ok so I always have to delete the node from both direction.
Do you think that in the future you’ll be able to implement the delete operation in a way that if it gets one uid (not a triple) it delete the node completely?

well, there are two nodes involved. I think your question is related to the incoming edges. And the answer is no, hardly an incoming edges delete op will be implemented.

There are some discussions about this here and old ones in Github issues. And the conclusion is that It doesn’t worth to implement. Is better for the user to do it manually or via Upsert other than implementing such an expensive feature that can happen to bring unusual behaviors.

Our recommendation is sticky to the upsert block.

Haa the reverse create 2 nodes? I thought it just create a bi-directional connection

No, you have. User is one node and ApiKeySet is another. The reverse edge doesn’t have anything to do with it. It is just useful in those cases with upsert block.

Dgraph is a Directed Graph Database. As Dgraph is a directed Graph. You have to deal with the edges in their respective nodes. You can’t edit a parent node from their child.

Ok I understand thanks a lot