Incoming edge from other node not deleted when deleting a node

let’s say a Person Mike has friend edge pointing to another person Sam, so we have something like:
{
uid: ‘xx1’
name: ‘mike’
friend: {
uid: xx2
name: sam
}
}
but then when I delete the node Sam with:

{
  delete {
     <xx2> * * .
  }
},

mike still has that edge like this:
{
uid: ‘xx1’
name: ‘mike’
friend: {
uid: xx2
}
}

this seems like in mysql we have deleted a record which is referred from another table using foreign key, this breaks consistency 'cause now uid xx2 does not exist any more, what’s the meaning leaving it there?

Hey @fengchangfight, I tried the same thing but it was working fine…

import json
import pydgraph

def create_client_stub():
    return pydgraph.DgraphClientStub('localhost:9080')


def create_client(client_stub):
    return pydgraph.DgraphClient(client_stub)


def drop_all(client):
    return client.alter(pydgraph.Operation(drop_all=True))


def set_schema(client):
    schema = """
    name: string @index(exact) .
    age: int .
    friend: uid @reverse .
    """
    return client.alter(pydgraph.Operation(schema=schema))


def create_data(client):
    txn = client.txn()
    try:
        p = {
            'name': 'Karandeep',
            'age': 25,
            'friend': [
                {
                    'name': 'Ayush',
                    'age': 25,
                }
            ]
        }
        assigned = txn.mutate(set_obj=p)

        txn.commit()
    finally:
        txn.discard()


def delete_data(client):
    #To Delete Data
    txn = client.txn()
    try:
        query1 = """query all($a: string)
        {   all(func: eq(name, $a)) 
            {   uid
            }   }"""
        variables1 = {'$a': 'Karandeep'}
        res1 = client.query(query1, variables=variables1)
        ppl1 = json.loads(res1.json)
        for person in ppl1['all']:
            print("Karandeep's UID is")
            print(person)
            print
            print


        assigned = txn.mutate(del_obj= person)

        txn.commit()

    finally:
        txn.discard()


def query_data(client):
    query = """query all($a: string)
        {   all(func: eq(name, $a)) 
            {   uid, name,   age
                friend { uid, name,age }
                ~friend { uid, name,age }
            }   }"""

    variables = {'$a': 'Karandeep'}
    res = client.query(query, variables=variables)
    ppl = json.loads(res.json)
    print(query)
    print
    print
    print

    print('Number of people named "Karandeep": {}'.format(len(ppl['all'])))
    for person in ppl['all']:
        print(person)
        print
        print
        print


def query_data01(client):
    query01 = """query all($b: string)
        {   all(func: eq(name, $b)) 
            {   uid, name,   age
                friend { uid, name,age }
                ~friend { uid, name,age }
            }   }"""

    variables01 = {'$b': 'Ayush'}
    res01 = client.query(query01, variables=variables01)
    ppl01 = json.loads(res01.json)
    print(query01)
    print
    print
    print

    print('Number of people named "Ayush": {}'.format(len(ppl01['all'])))
    for person in ppl01['all']:
        print(person)
        print
        print
        print


def main():
    client_stub = create_client_stub()
    client = create_client(client_stub)
    drop_all(client)
    set_schema(client)
    create_data(client)
    query_data(client)
    query_data01(client)
    delete_data(client)
    query_data(client)
    query_data01(client)

    client_stub.close()


if __name__ == '__main__':
    try:
        main()
        print('\nDONE!')
    except Exception as e:
        print('Error: {}'.format(e))

This is what Output I got from this -

query all($a: string)
        {   all(func: eq(name, $a)) 
            {   uid, name,   age
                friend { uid, name,age }
                ~friend { uid, name,age }
            }   }



Number of people named "Karandeep": 1
{u'age': 25, u'uid': u'0x9e', u'friend': [{u'age': 25, u'uid': u'0x9f', u'name': u'Ayush'}], u'name': u'Karandeep'}



query all($b: string)
        {   all(func: eq(name, $b)) 
            {   uid, name,   age
                friend { uid, name,age }
                ~friend { uid, name,age }
            }   }



Number of people named "Ayush": 1
{u'age': 25, u'~friend': [{u'age': 25, u'uid': u'0x9e', u'name': u'Karandeep'}], u'uid': u'0x9f', u'name': u'Ayush'}



Karandeep's UID is
{u'uid': u'0x9e'}


query all($a: string)
        {   all(func: eq(name, $a)) 
            {   uid, name,   age
                friend { uid, name,age }
                ~friend { uid, name,age }
            }   }



Number of people named "Karandeep": 0
query all($b: string)
        {   all(func: eq(name, $b)) 
            {   uid, name,   age
                friend { uid, name,age }
                ~friend { uid, name,age }
            }   }



Number of people named "Ayush": 1
{u'age': 25, u'uid': u'0x9f', u'name': u'Ayush'}

thanks for the long answer, but I think your example is Karandeep->friend->Ayush, and then you delete Karandeep right? what I did wasn’t deleting Karandeep, but deleting Ayush, and after deleting Ayush, I still got Karandeep with an edge pointed to Ayush uid(although not valid any more)

Hi.

I think the confusion here is that

{
  delete {
     <xx2> * * .
  }
}

doesn’t delete the node. It deletes all the edges out of the node. It’s different to the mysql case you quote because there isn’t a notion of tables or foreign keys here. The edge you refer to is still valid, because you’ve deleted edges out of the node, not edges into the node, or the node itself.

Extending Michael’s point, Dgraph doesn’t have a separate storage for nodes. They’re just part of the edges. So, if you’re querying for the edge, and it has a node, it would show up – but given you deleted all the edges from that node, no further expansion from that node would happen.

Thanks for the answer, that make sense, one more question, how to I delete that node entirely? According to @mrjn 's answer, dgraph does not have separate storage for nodes, just part of edges, does that mean if I delete all incoming edges for that node as well, then conceptually, that node is totally removed?

Hi. Yes, delete all edges into and out of a node and it’s no longer in the graph.

1 Like

Here it is, I just wondering how to delete the node itself?
Really hope to get an answer,Thanks XD