Create new node or add existing node to a graph

I have a graph of different ids. My requirement is I want to add a new pair to the system. But I am not sure if both the pair exists or not. It could be that
u1 exists and u2 doesn’t
u1 doesn’t exist and u2 exists
u1 and u2 both exist
u1 and u2 both are not there.
So, can I do all of the operations in a single upsert block ?

type:

type IdNode {
  idval: string 
  idtype: string
  ts: int 
  conn: [IdNode] 
}
idval: string @index(exact) .

data:

{
	set {
		_:uuid1 <idval> "uuid1" .
		_:uuid1 <idval> "uuid" .
		_:uuid1 <dgraph.type> "IdNode" .
		_:uuid1 <ts> "12313223211" .
		_:uuid1 <conn> _:gm1 .

		_:gm1 <idval> "mygmail.com" .
		_:gm1 <idtype> "gmail" .
		_:gm1 <dgraph.type> "IdNode" .
		_:gm1 <ts> "12313223213" .

		_:uuid2 <idval> "uuid2" .
		_:uuid2 <idtype> "uuid" .
		_:uuid2 <dgraph.type> "IdNode" .
		_:uuid2 <ts> "12313223212" .
		_:uuid2 <conn> _:gm1 .

		_:uuid3 <idval> "uuid3" .
		_:uuid3 <idtype> "uuid" .
		_:uuid3 <dgraph.type> "IdNode" .
		_:uuid3 <ts> "12313223212" .
		_:uuid3 <conn> _:uuid2 .

		_:eid <idval> "eid" .
		_:eid <idtype> "eid" .
		_:eid <dgraph.type> "IdNode" .
		_:eid <ts> "12313223212" .
		_:eid <conn> _:uuid1 .

		_:fb <idval> "fb.com" .
		_:fb <idtype> "fb" .
		_:fb <dgraph.type> "IdNode" .
		_:fb <ts> "12313223212" .
		_:fb <conn> _:uuid1 .
	}
}

questions

  • insert uuid9 and fb.com mapping. (in this case uuid9 doesn’t exist and fb.com is present)
  • insert uuid9 and uuid10 mapping. (in this case both don’t exist, so the system should create two nodes and join them together)
  • connect eid and mygmail.com. (in this case both exist and are not connected, so connect them)
  • connect eid and uuid.(dont do anything, as they are already connected)

Can we do all of the above query in a single upsert block?

I think your queries in question have multiple values of the “uuid9” , either it can be connected to “fb.com” or “uuid10”. I guess you stated this just for example. Well ,you can have multiple queries in the upsert like below and create “uuid9” and conncet it to “fb” in mutation part . Similarly you can add values for eid or any other node also in the same mutation part.

upsert {
  query {
   q(func: eq(idval, "uuid9")) {
      u9 as uid
    }
   q(func: eq(idval, "fb.com")) {
      f as uid
    }
  q(func: eq(idval, "eid")) {
      e as uid
    }
  q(func: eq(idval, "uuid1")) {
      u1 as uid
    }
   
  }

  mutation {
    set {
                
         uid(u9) <idval> "uuid9" .
		 uid(u9) <idtype> "uuid" .
		 uid(u9)<dgraph.type> "IdNode" .
		 uid(u9)<ts> "12313223212" .
		 uid(u9) <conn> uid(f) .

    }
  }
}

but how can I make sure that if two nodes exist and are already connected directly then not to do anything just skip. I am not able to figure out that part.

If nodes already exists then query parts will return uid of those and in mutation part where we add “conn” will automatically get skipped. For example if “uuid9” and “fb.com” are already connected then mutation part below get skipped.

upsert {
  query {
   q(func: eq(idval, "uuid9")) {
      u9 as uid
    }
   q(func: eq(idval, "fb.com")) {
      f as uid
    }
}
 mutation {
    set {
		 uid(u9) <conn> uid(f) .

    }
    
}

I hope this clear your doubt.