Best way to check if an edge exists between two nodes

I have come up with some madly elaborate ways to check if the edge between two nodes exists (direct or reverse), but I’m thinking there must be a better way.

Right now I’m doing a weirdly elaborate query for both edge directions between two nodes. I do have a @reverse index set on the edge, so I’m thinking there must a better i.e. more elegant way to check if the edge exists than this:

{
  node(func: eq(xid, "object2")) {
    uid
    link @filter(eq(xid, "object1")) {
      uid
    }
    ~link @filter(eq(xid, "object1")) {
      uid
    }
  }  
}
1 Like

Well, if you doing what I’m thinking you doing. There is only that way. But, you really mean “check if an edge exists”. You should use has() func tho.

{
  node(func: eq(xid, "object2")) @filter(has(link) AND has(~link)) {
    uid
  }  
}

You could use uid_in() in other cases too.

You could also do

{
  A as var(func: eq(xid, "object2")) @cascade {
    uid
    link @filter(eq(xid, "object1")) {
      uid
    }
    ~link @filter(eq(xid, "object1")) {
      uid
    }
  } 
  node(func: uid(A)) { 
      uid
  }
}

I like the first suggestion – I did not think of using has function, though the suggestion does not check if the link (or reverse link) exists to a specific node. It only checks if any link exists, right?

What I’m after is checking the link (direct or reverse) between two specific nodes, so using the latter suggestion does the trick, but its pretty much almost the same as my original approach.

I actually also need to read in the facets if either direct or reverse edge exists, so might end up doing this:

{
  node(func: eq(xid, "object2")) @cascade {
    uid
    dlink as link @filter(eq(xid, "object1")) @facets(dtype as type, dweight as weight) {
      uid
    }
    rlink as ~link @filter(eq(xid, "object1")) @facets(rtype as type, rweight as weight) {
      uid
    }
  }
  
  dirobj(func: uid(dlink)) {
    name
    xid
    relation: val(dtype)
    weight: val(dweight)
  }
      
   revobj(func: uid(rlink)) {
    name
    xid
    relation: val(rtype)
    weight: val(rweight)
  }
}

This looks ugh…not nice at all :slight_smile:

I also noticed one thing. In my case, weight is a facet on link edge. It is a float value as you’d expect, but when I don’t set it (i.e. when its value is set to 0.0) then when I query for all facets on the edge it does not seem to be returned in the resulting JSON. However, if I set it to non-0 value it is indeed set and returned properly. What gives?

Has func checks if there is an edge. Either a value edge or an outgoing edge. But it doesn’t checks the values.

There is a small difference. The cascade directive will return only if all the requests are true. Without cascade, it would return even if missing one or more nodes in the query logic.

Not sure what is happening, need further investigation.