Upserting a parent with multiple children

Hi, I was hoping to upsert a multiple nodes at once. For example, I want to supply a graph that has a parent and two children. The upsert would populate any of those nodes that did not exist, and update the nodes that did exist.

Using the upsert block I was able to pull this off with graphs that had single children in the relationship, but am now stuck when there’s multiple children. I want to write something like so:

upsert {
  query {
    q(func: eq(name, "parent1")) {
      v as uid
      name
      has_child @filter(eq(name, "child1")){
        v2 as uid
      }
      has_child @filter(eq(name, "child2")){
        v3 as uid
      }
    }
  }

  mutation {
    set {
      uid(v) <name> "parent1" .
      uid(v) <has_child> uid(v2) .
      uid(v) <has_child> uid(v3) .
      uid(v2) <name> "child1" .
      uid(v3) <name> "child2" .
    }
  }
}

However specifying multiple <has_child> relationships is forbidden. What would be the most idiomatic way to solve this?

It should be successful. What is the error?

BTW, no need to add this. Unless you really wanna change their name.

@MichelDiz The error I get is Error: t: : while converting to subgraph: has_child not allowed multiple times in same sub-query.

I’m using dgraph 1.1.1

Can you check if the has_child is 1:1 or 1 to many in your schema?
e.g:
has_child: uid . = 1:1
and
has_child: [uid] . = 1:Many

@MichelDiz Thanks for responding- in my schema it is one to many:

<has_child>: [uid] .

Oh, I just noticed the issue. You have to use an alias when using the same edge multiple times in the same block.

Here is the solution

upsert {
  query {
    q(func: eq(name, "parent1")) {
      v as uid
      name
      has_child @filter(eq(name, "child1")){
        v2 as uid
      }
      has_child2: has_child @filter(eq(name, "child2")){
        v3 as uid
      }
    }
  }

  mutation {
    set {
      uid(v) <name> "parent1" .
      uid(v) <has_child> uid(v2) .
      uid(v) <has_child> uid(v3) .
      uid(v2) <name> "child1" .
      uid(v3) <name> "child2" .
    }
  }
}

@MichelDiz Ahh awesome thanks! I actually tried that with the has_child2 AS has_child syntax but I see thats for variablizing and not aliasing. Works great :slight_smile: