Conditional Upsert/Mutation using a scalar variable and Val function

Hi
I am trying to use the query variable to update a scalar predicate (list of string type) from one node to another but it is not working. Both the “abc123” and “xyz123” nodes exist and the stringlist predicate for xyz123 is non-empty. It looks the val() function only works in the context of the uid(fromUid) but what is the correct way to update an existing node’s scalar predicate (list of string type) with value of the same predicate from a different node.

e.g. This is not working as intended - stringlist predicate is not updated in toUid node.

upsert {
    query {
    var(func: eq(someId, "abc123")) {
            toUid as uid
    }
    var(func: eq(someId, "xyz123")) {
      	fromUid as uid
      	h as stringlist
     }  
  }
  mutation @if(eq(len(toUid), 1) AND eq(len(fromUid), 1)) {
    set {
      uid(toUid) <stringlist> val(h) .
    }
  }
}
1 Like

Actually, I got

“message”: “: Value variables not supported for predicate with list type.”

So, val doesn’t support list type. That should be a request.

Sample dataset

{
   "set": [
      {
         "someId": "abc123"
      },
      {
         "someId": "xyz123",
         "stringlist": [
            "Grape",
            "Apple",
            "Strawberry",
            "Banana",
            "watermelon"
         ]
      }
   ]
}
1 Like

Thanks Michel for the reply

There are couple of issues I see here - both related to inconsistent behavior.

  1. If the stringlist has one element then there is no “Value variables not supported for predicate with list type.” error but still silently fails.
  2. If the predicate is an edge list or edge then it can be moved/set between nodes but if the predicate is a scalar type then there is no way to move then within upsert query afaik.

Is this something that can be fixed in the future releases?

I think you are in a old version. I’m using 20.07.0 and it worked fine with a single value. But it should throw an error instead. As it is not supported.

Yeah, relational edges works differently than a List type.

Yeah, cuz you have to do like this

upsert {
    query {
    var(func: eq(someId, "abc1234")) {
            toUid as uid
    }
    var(func: eq(someId, "xyz1234")) {
      	fromUid as uid
      	h as stringlist
     }
      me(){
        newH as max(val(h))
      }
  }
  mutation @if(eq(len(toUid), 1) AND eq(len(fromUid), 1)) {
    set {
      uid(toUid) <stringlist> val(newH) .
    }
  }
}

I have an issue for this case but was decided for now to maintain this kind of pattern.

You can follow the whole story bellow

https://github.com/dgraph-io/dgraph/issues/4779

https://github.com/dgraph-io/dgraph/issues/4712

I am using the dgraph/standalone:v20.07.1 image