Is it possible to clone a node in one transaction?

If you have a node’s uid and you’d like to create a new node with some predicate values copied over, can you do that in one transaction or do you have to query and then set a new node?

Hi @MiLeung
Unfortunately, there is no direct clone function supported yet. You could explore the upsert block.

In this example, I was able to “clone” a string and an int value. However the upsert has to be run twice (explained below).
Source Data:

{
  set{
    _:a <name> "andy" .
    _:a <age> "30" .
  }
}

Upsert Block
This needs to be run twice; once to create and link a clone node, and in the second run, clone the value themselves. In order to yield a single scalar value for respective attributes from the source, I had to use an aggregate function.

upsert{
  query{
    source as var(func:uid(<0xc>)){
      clone as clonedTo
    }

    clonedFrom(func: uid(clone)){
      ~clonedTo{
        a as age
        n1 as name
      }
      x as max(val(a))
      xn as max(val(n1))
    }
  }
  mutation {
    set{
      uid(source) <clonedTo> uid(clone) .
      uid(clone) <name> val(xn) .
      uid(clone) <age> val(x) .
    }
  }
}

There is worked out solution here for edges in a data merging context here. Please review that as well.

1 Like

IMO we should consider supportingfirstValue as an aggregate function. That would help to solve such requirements without resorting to max functions. It would be an elegant solution.

1 Like

Thanks. I would also need functionality to clone a node’s uid value predicates, so I’ll just have to use a query then set mutation for now.