Delete edge along with all values of pointing node


#1

I have following graph structure -

{
    Uid: 001,
	Question.Title: “Title” 
	// Other values
	Answer {
		uid: 002,
		answer.body: “Blah blah blah”,
		//other values
		comment {
			uid: 003,
			comment.body: “this is comment”,
			//other values
		}
	}
}

DeleteJson

{
	Uid: 002,
	comment {
		uid: 003
	}
}

When above mutation is done only the edge of ‘comment’ between <002> and <003> is deleted. I want to delete the edge as well as all the values from node <003>. How to do that in a single mutation?


(Michel Conrado) #2

Delete only the UID “003” - So your application will only collect the UIDs from the comments and only delete these. You do not need to format an entire object for this process. Just know the UID of the comment.

{
		"delete": [
			{
				"uid": "0x3"
			}
		]
	}

There will no longer be any relation or predicate in the comment Node.

More details: https://docs.dgraph.io/mutations/#deleting-edges

Let’s say you wanna delete 6 comments in one batch:

{
		"delete": [
			{
				"uid": "0x3"
			},
            {
				"uid": "0xa"
			},
            {
				"uid": "0xa22"
		    },
            {
				"uid": "0x2714"
		    }
            {
				"uid": "0x2716"
			},
            {
				"uid": "0x2713"
			}
		]
	}

This was updated well below


Hard time trying do delete things
#3

Thanks a lot.
So If I have to delete entire question node then I have to delete all its child nodes.
e.g. In above case, I have to collect all the Uids of Answers and their comments and delete these uids right?

One more thing

I have count(comment) in my query. So If I delete just comment uid then does it show one number less in count(comment) ?


(Michel Conrado) #4

Collect all UIDs (parent and childs) from the Question and then queue them for deletion.

Count is used only by UIDs, if you delete UIDs the predicate or Root query you make will come with fewer values. Even if you just cut the node’s relationship (instead of deleting the entire Node) such as “undoing friendship” decreases count in (friends).
So the answer is, Yes.


#5

Ok. Got it.
Thank You.:smiley:


#6

I did as you said, I deleted only the comment UID but I am not getting a lesser values in my count(comment) . Suppose I have 4 comments and then I delete one of them by using the UID. So when I query again, I still get count(comment) = 4.
It is mentioned here in the docs https://docs.dgraph.io/mutations/#delete , that
The pattern S * * deletes all edges out of a node (the node itself may remain as the target of edges), any reverse edges corresponding to the removed edges and any indexing for the removed data.

So when I just deleted the comment node by using a single comment UID, it deleted only the edges out of the comment node.

I checked the deleted node by using its UID in ratel. It shows that all the values of the comment node are deleted but the UID itself is still present. Is it because of that my count is not updating?

As You can see in here, the Answer node has comment as an outward edge. So in order to get the count one less number after deleting a single comment I have to delete the edge too between Answer and comment as I was doing previously?

I am sorry, I am confusing something.


Hard time trying do delete things
(Michel Conrado) #7

This is weird. We are investigating this.

For now use this temporary solution
some(func: has(__User)) @filter( eq(isActive, true) AND (not has(__deleted))) #optional

{
  test(func: has(Question.Title)){
    uid
    Question.Title
    Answer {
      uid
      answer.body
      comment @filter(has(comment.body) ) { 
        uid 
        comment.body
            }
       }
  }
}

Hard time trying do delete things
#8

1.@MichelDiz, the problem is with count(comment). My query returns 3 comments but returns count(comment) = 4 after deletion of one comment node with UID.
EDIT -
By using filter in the count() like count(comment @filter(has(comment.body)) I am getting the correct number of comments.
This works but I think filter in count adds extra overhead to the query.

For getting the UIDs of child I am doing something like this -

           var(func: uid($a)) {
                Answer {
                    AnswerUids as uid
                    Comment {
                       commentUids as uid
                    }
                }
            }
            uids(func: uid(AnswerUids, commentUids)){
                uid
            }

I am using node.js client. So iterating over array in node.js is memory consuming. So I want to collect all the UIDs for deletion from query itself.
So am I doing it correctly? If no then how to do it efficiently?


(Michel Conrado) #9

I don’t believe so, It should not scratch too much. For now this is the temporary solution. This was not happening before, it could be a bug. Waiting this week for an answer on that. There is a similar case being analyzed, but it is only related.

On Node JS I do not have much to say (about efficiency and etc). As for the query there is no performance problem in it. It’s the way I would do to collect such UIDs. But this query you describe will erase all responses and comments from a thread. You have to have one for the whole thread, one for all of the thread’s answers and one for all of the response comments.


#10

By the way, I am not using the latest version of Dgraph. The version on my machine is 1.0.3. Are you getting the same issue with the current latest version 1.0.6 ? I will be waiting for its fix if its a bug.

Yes you are right. I have to include the thread’s UID to in order to delete the whole thread.
Thank you.


(Michel Conrado) #11

Hey! Now a little more focused, I realized that I made a mistake. The right thing was to do the Delete like this:

{
		"delete": [
{
     "uid": "0x2", #Answer UID
     "comment": {
       "uid": "0x3" #Comment
        }
    },
{
	"uid": "0x3" #Comment final delation
			}
]
	}

This way you delete the UID that is in the parent’s predicate and then the comment itself. That was a mistake, have to do in order. I was wrong since I need to build the relationship in JSON/Del for deletion.

The queue what I exemplified up there deletion must be done that way.

{
		"delete": [
{
     "uid": "0x2",
     "comment": {
				"uid": "0x3"
			},
{
     "uid": "0x2",
     "comment": {
				"uid": "0xa"
			},
{
     "uid": "0x2",
     "comment": {
				"uid": "0xa22"
		    },
{
     "uid": "0x2",
     "comment": {
				"uid": "0x2714"
		    },
{
     "uid": "0x2",
     "comment": {
				"uid": "0x2716"
			},
{
     "uid": "0x2",
     "comment": {
				"uid": "0x2713"
			},

{
				"uid": "0x3"
			},
            {
				"uid": "0xa"
			},
            {
				"uid": "0xa22"
		    },
            {
				"uid": "0x2714"
		    }
            {
				"uid": "0x2716"
			},
            {
				"uid": "0x2713"
			}
		]
	}

Deleting nodes?
Hard time trying do delete things
#12

@MichelDiz I did as you told above. Its working. Thanks.
But when I delete the edge and node itself still there is a node with UID is present.
e.g.-

{
"delete": [
  {
       "uid": "0x2", #Answer UID
       "comment": {
          "uid": "0x3" #Comment
        }
   },
  {
	"uid": "0x3" #Comment final delation
  }
 ]
}

As you can see, the comment node with UID <0x3> had only one incoming edge from <0x2> which I deleted and the comment node with UID <0x3> itself is deleted. So when I query after deletion it still shows the comment node with UID <0x3>. So, will that comment node with UID <0x3> remain forever even if there are no edges going out and coming in? Is it desired as per Dgraph’s architecture?


(Michel Conrado) #13

Dgraph keeps the UID there, but consider it discarded. However, you can use it. For some reason you want to use this discarded UID I could think of a strategy for you. But technically it’s irrelevant, because you’ll have to keep complicated logic on your back-end running a background work just to use discarded UIDs.