Upsert creates an empty node when query variable is empty

I Want to Do

I want to query for a set of nodes, and then assign those nodes as the target of new edges.

What I Did

I run an upsert like this:

upsert {
  query {
    p1 as var(func: eq(xid, "EXT_ID")) @recurse {  
      child as children
    }
  }

  mutation {
    set {
      uid(p1) <ecosystem> uid(child) .
    }
  }
}

However, even if the “EXT_ID” don’t have any children (meaining the child variable is empty), a new edge <ecosystem> from p1 to a new empty node is created.

This is, even if the query

{
  p1(func: eq(xid, "EXT_ID")) {  
    eco as children {
      uid
    }
  }
  eco(func: uid(eco)) {
    uid
  }
}

returns empty,

"data": {
    "p1": [],
    "eco": []
  },

the upsert shown above results in a new node being returned from the query

{
  perspectives(func: eq(xid, "EXT_ID")) {        
    ecosystem {
      uid
    }
  }
}

The result of the query before running the upsert:

 "perspectives": [
      {
        "ecosystem": [
          {
            "uid": "0x111704"
          },
          {
            "uid": "0x113e11"
          }
        ]
      }
    ]

and after running the upsert

 "perspectives": [
      {
        "ecosystem": [
          {
            "uid": "0x111704"
          },
          {
            "uid": "0x113e11"
          },
          {
            "uid": "0x113e12"
          }
        ]
      }
    ]

Dgraph Metadata

docker image dgraph/standalone:v20.03.3
ubuntu 20

That’s the upsert behave. If you wanna more control you should use Conditional Upsert.

1 Like

Thanks @MichelDiz :slight_smile: