# Bulk/massive upserts feature

**URL:** <https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928>\
**Category:** Dev\
**Created:** [August 15, 2019, 3:20am UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928 "2019-08-15T03:20:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![MichelDiz](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/micheldiz/32/11873_2.png) [@MichelDiz](https://discuss.dgraph.io/u/MichelDiz)\
**Post date:** [August 15, 2019, 3:20am UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928/1 "2019-08-15T03:20:50Z")

</div>

Hey @amanmangal, I saw [Add support for multiple mutations in an upsert query · Issue #3817 · dgraph-io/dgraph · GitHub](https://github.com/dgraph-io/dgraph/issues/3817)  
what about the “bulk/massive upsert” thing I’ve mentioned 2 months ago? Do you think it should be a new issue or related to 3817?

> “How to Update millions or records in a table” a common SQL question.

The ref query.

```auto
upsert {
      query {
          me(func: regexp(email, /^*@dgraph.io*$/)) {
          v as uid
        }
      }
        mutation {
          set {
            uid(v) <WorksAt> "Dgraph Labs" . 
            #fix typo "Dgraph Lab" to "Dgraph Labs"
          }
      }
}

```

If Dgraph finds 40 workers at “@dgraph.io”, we create 40 Nquads Clones with different uids or 40 mutation blocks. To add or update a new information.

This would be useful for games scenarios (distributing score to groups of a game), social networks, contextualized changes(like, someone typo the company’s name and we need to alter it in several context levels - could means thousands of nodes) and so on.

```auto
upsert {
      query {
          me(func: eq(team, "Manchester United RPG Club")) {
            rpgTeam {
                    v as uid
             }
        }
      }
        mutation {
          set {
            uid(v) <overallTeamScore> "3000" .
          }
      }
}

```

Also this could be a kind of “drop/clean”. We need to delete a company from our DB. Let’s say that yellow company here has 2k employees. After delete all yellow’s information I wanna delete all employees from my DB due legal reasons.

```auto
upsert {
      query {
          me(func: regexp(email, /^*@yellow.company*$/)) {
          v as uid
        }
      }
        mutation {
          delete {
            uid(v) * * .
          }
      }
}

```

Also delete a thread posts from a social network

```auto
upsert {
      query {
          me(func: regexp(username, "@MichelDiz")) {
          posts @filter(eq(postID, "156358129154782120") {
                 POST as uid
                 rootcmts as comments {
                  TH as thread {
                   cmts as comments {
                   WHO as ~commented
                    }
                  }
                }
            }
        }
      }
        mutation {
          delete {
            uid(POST) * * .
            uid(rootcmts) * * .
            uid(TH) * * .
            uid(cmts) * * .
            uid(WHO) <commented> uid(cmts) . #This deletes a reverse edge 
                                              #from users that commented there.
          }
      }
}

```

---

<div class="post-metadata">

**Author:** ![amanmangal](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amanmangal/32/1249_2.png) [@amanmangal](https://discuss.dgraph.io/u/amanmangal)\
**Post date:** [August 15, 2019, 3:58am UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928/2 "2019-08-15T03:58:10Z")

</div>

All of this should work in master. The PR [Add support for conditional mutation in Upsert Block by mangalaman93 · Pull Request #3612 · dgraph-io/dgraph · GitHub](https://github.com/dgraph-io/dgraph/pull/3612) adds support for this along with conditional Upsert. It would be really useful if you could try these on master and share your experience reports. Share the examples here, I could use them for an Upsert Blog too.

---

<div class="post-metadata">

**Author:** ![MichelDiz](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/micheldiz/32/11873_2.png) [@MichelDiz](https://discuss.dgraph.io/u/MichelDiz)\
**Post date:** [August 15, 2019, 3:43pm UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928/3 "2019-08-15T15:43:58Z")

</div>

Perfect! Wonderful work Aman!

forget this =\>_But only `S * *` deletion isn’t working._

Uh! I’ve forgot I need Types to be able delete!

---

<div class="post-metadata">

**Author:** ![MichelDiz](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/micheldiz/32/11873_2.png) [@MichelDiz](https://discuss.dgraph.io/u/MichelDiz)\
**Post date:** [August 15, 2019, 4:06pm UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928/4 "2019-08-15T16:06:55Z")

</div>

Another way to do this [dgraph/upsert\_test.go at d6af37853169fccd5b266606c8d23beacdb66187 · dgraph-io/dgraph · GitHub](https://github.com/dgraph-io/dgraph/blob/d6af37853169fccd5b266606c8d23beacdb66187/dgraph/cmd/alpha/upsert_test.go#L342)

Actually, I think it would be better than using “first:”. Because there may be several people with 56 years. So they should all take the title “oldest” and not a random one.

It would be perfect if the aggregation could pass the UID along with the value. That way I wouldn’t have to do another round trip block. And also I wouldn’t need to add an index to age pred.

```auto
upsert {
  query {
    has_age as var(func: has(age)) {
      a as age
    }
    var() {
    MAX as max(val(a))
  }
    u as var(func: uid(has_age)) @filter(eq(age, val(MAX)))
  }
  mutation {
    set {
      uid(u) <oldest> "true" .
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![amanmangal](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amanmangal/32/1249_2.png) [@amanmangal](https://discuss.dgraph.io/u/amanmangal)\
**Post date:** [August 16, 2019, 12:49am UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928/5 "2019-08-16T00:49:50Z")

</div>

- I think this particular test is older test written to test Upsert where a variable can only take one value.
- `S * *` probably doesn’t work because tests do not have type information.

---

<div class="post-metadata">

**Author:** ![MichelDiz](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/micheldiz/32/11873_2.png) [@MichelDiz](https://discuss.dgraph.io/u/MichelDiz)\
**Post date:** [August 22, 2019, 1:03am UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928/6 "2019-08-22T01:03:04Z")

</div>

Hey, can we support value variables in upsert mutation?

```auto
upsert {
      query {
          me(func: eq(team, "Manchester United RPG Club")) {
            rpgTeam {
                    v as uid
                    OVTS as overallTeamScore
             }
            mySum as math(3000+ val(OVTS)) # let's say 3k + 5500
        }
        mutation {
          set {
            uid(v) <overallTeamScore> val(mySum) .
          }
      }
}

```

I also think that “`val ()`” would be a wayout for dealing with facet changes. As I mention in my last comment in this issue below.

[https://github.com/dgraph-io/dgraph/issues/1996](https://github.com/dgraph-io/dgraph/issues/1996)

---

<div class="post-metadata">

**Author:** ![amanmangal](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amanmangal/32/1249_2.png) [@amanmangal](https://discuss.dgraph.io/u/amanmangal)\
**Post date:** [August 22, 2019, 1:29am UTC](https://discuss.dgraph.io/t/bulk-massive-upserts-feature/4928/7 "2019-08-22T01:29:09Z")

</div>

Thanks for pointing it out. This is already on our roadmap and in my todo list as I have mentioned before. Good chance it won’t be available in 1.1 though. But this is a feature that doesn’t require API change, should be easy enough (from API perspective) to add in say 1.1.1.
