# Upserting for a list of predicates

**URL:** <https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338>\
**Category:** Dgraph\
**Created:** [June 23, 2020, 5:21pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338 "2020-06-23T17:21:11Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![RJKeevil](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rjkeevil/32/2625_2.png) [@RJKeevil](https://discuss.dgraph.io/u/RJKeevil)\
**Post date:** [June 23, 2020, 5:21pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/1 "2020-06-23T17:21:11Z")

</div>

Hi, i’ve read through the upsert docs at [https://dgraph.io/docs/mutations/#upsert-block](https://dgraph.io/docs/mutations/#upsert-block) but can’t figure out how to acheive the following scenario, help greatly appreciated!

I have a list of values that may or may not exist in dgraph. In a single upsert block, I want to query for nodes based on these predicates (e.g. (func: eq(uniqueValue, [“abc”,“def”,“ghi”]))). For each predicate, if no node/uid is found, I want to create a new uid and set uniqueValue to this value. Lastly I need to get back the complete list of uid-uniqueValue pairs, whether they existed already or were created by the upsert.

I can make this work if i use one upsert block per uniqueValue, but that does not perform very well for the amount of data. Is this possible?

---

<div class="post-metadata">

**Author:** ![minhaj](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/minhaj/32/3468_2.png) [@minhaj](https://discuss.dgraph.io/u/minhaj)\
**Post date:** [June 24, 2020, 9:35am UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/2 "2020-06-24T09:35:07Z")

</div>

Hi @RJKeevil, You can perform this mutation in one upsert block. I have written a sample upsert block below.

```auto
upsert {
  query {
    q1(func: eq(uniqueValue, "abc")) {
      v1 as uid
     uniqueValue
    }
    q2(func: eq(uniqueValue, "def")) {
      v2 as uid
      uniqueValue
   }
   q3(func: eq(uniqueValue, "ghi")) {
      v3 as uid
      uniqueValue
    }
  }
  mutation {
    set {
      uid(v1) <uniqueValue> "$val1" .
      uid(v2) <uniqueValue> "$val2"
      uid(v3) <uniqueValue> "$val3" .
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![RJKeevil](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rjkeevil/32/2625_2.png) [@RJKeevil](https://discuss.dgraph.io/u/RJKeevil)\
**Post date:** [June 24, 2020, 9:41am UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/3 "2020-06-24T09:41:27Z")

</div>

Thanks for the response, I will test straight away. So in the case that the uniqueValue already exists with a Uid, will the mutation be a no-op? Or will it be executed, but result in no change to the graph?

---

<div class="post-metadata">

**Author:** ![minhaj](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/minhaj/32/3468_2.png) [@minhaj](https://discuss.dgraph.io/u/minhaj)\
**Post date:** [June 24, 2020, 9:43am UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/4 "2020-06-24T09:43:46Z")

</div>

If any of the uniqueValue already exist, it will be executed but there will be no change(if you keep new uniqueValue to be the same as older).

---

<div class="post-metadata">

**Author:** ![RJKeevil](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rjkeevil/32/2625_2.png) [@RJKeevil](https://discuss.dgraph.io/u/RJKeevil)\
**Post date:** [June 24, 2020, 12:24pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/5 "2020-06-24T12:24:16Z")

</div>

Thank you @minhaj , I almost have this working fully with the following code:

```auto
    values := []string{"abc","def","ghi"}
	var queries []string
	var mutations []*api.Mutation
	for i, value := range values {
		a := strconv.Itoa(i+1)
		queries = append(queries, fmt.Sprintf(`{q%s(func: eq(uniqueValue, "%s")) {v%s as uid uniqueValue}}`, a, value, a))
		mutations = append(mutations, &api.Mutation{
			SetNquads: []byte(fmt.Sprintf(`uid(v%s) <uniqueValue> "%s" .`, a, value)),
		})
	}

	request := &api.Request{
		Query: strings.Join(queries, "\n"),
		Mutations: mutations,
		CommitNow: true,
	}

	response, err := dgraphClient.NewTxn().Do(context.Background(), request)
	util.Check(err)

	fmt.Println(response.Uids)

```

Interestingly, it only prints the Uids for uniqueValues that do not exist already in dgraph. Thats hopefully a good sign for efficiency, as it is detecting the others can be skipped? Unfortunately, I need those preexisting Uids too 🙂

I could follow up with a second query for these, but I really want to do this in a single query if possible.

---

<div class="post-metadata">

**Author:** ![minhaj](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/minhaj/32/3468_2.png) [@minhaj](https://discuss.dgraph.io/u/minhaj)\
**Post date:** [June 24, 2020, 12:28pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/6 "2020-06-24T12:28:21Z")

</div>

Can you show me the full JSON response of this mutation?

---

<div class="post-metadata">

**Author:** ![RJKeevil](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rjkeevil/32/2625_2.png) [@RJKeevil](https://discuss.dgraph.io/u/RJKeevil)\
**Post date:** [June 24, 2020, 12:31pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/7 "2020-06-24T12:31:48Z")

</div>

Unfortunately fmt.Println(string(response.Json)) just gives the following:

```auto
{"q1":[],"q2":[],"q3":[]}

```

I seem to get this for all upserts in the dgo client, perhaps that is a bug.

---

<div class="post-metadata">

**Author:** ![minhaj](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/minhaj/32/3468_2.png) [@minhaj](https://discuss.dgraph.io/u/minhaj)\
**Post date:** [June 24, 2020, 1:21pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/8 "2020-06-24T13:21:13Z")

</div>

Can you tell me Schema of your use case which will help me to reproduce the error.

---

<div class="post-metadata">

**Author:** ![RJKeevil](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rjkeevil/32/2625_2.png) [@RJKeevil](https://discuss.dgraph.io/u/RJKeevil)\
**Post date:** [June 24, 2020, 1:30pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/9 "2020-06-24T13:30:00Z")

</div>

The code above should be everything you need to reproduce I think, but the Type for this Uid is called Key and it has the following predicates

```auto
type: string @index(hash) .
value: string @index(hash) .
uniqueValue: string @index(hash) .

```

I tried modifying the code above to include setting things like dgraph.type and these additional fields, but it made no difference for me.

Im running the latest dgo cleint (V200) and the Jun22 beta, but I think this happens on all versions, ill test in a sec.

---

<div class="post-metadata">

**Author:** ![minhaj](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/minhaj/32/3468_2.png) [@minhaj](https://discuss.dgraph.io/u/minhaj)\
**Post date:** [June 24, 2020, 3:52pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/10 "2020-06-24T15:52:10Z")

</div>

I think you are starting with blank data every time you are performing the above upsert, that is why response.Json seems to be empty. I haven’t tried it on dgo yet, but if any of the uniqueValue is present already then response.json must not be empty. For the sake of simplicity, can you upload the complete code for the upsert and let me check. Otherwise, there must be some issues.

---

<div class="post-metadata">

**Author:** ![RJKeevil](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rjkeevil/32/2625_2.png) [@RJKeevil](https://discuss.dgraph.io/u/RJKeevil)\
**Post date:** [June 24, 2020, 6:17pm UTC](https://discuss.dgraph.io/t/upserting-for-a-list-of-predicates/7338/11 "2020-06-24T18:17:00Z")

</div>

You’re right, matching results are returned via response.Json, updated uids are present in the response.Uids. My dgraph instance was being inadvertently cleared between tests. Thanks!
