# External IDs and Upsert Block - Mutations

**URL:** https://discuss.dgraph.io/t/external-ids-and-upsert-block-mutations/11926
**Category:** Documentation
**Created:** [December 16, 2020, 8:00am UTC](https://discuss.dgraph.io/t/external-ids-and-upsert-block-mutations/11926 "2020-12-16T08:00:56Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![diggy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/diggy/32/3666_2.png) [@diggy](https://discuss.dgraph.io/u/diggy)
#### Post date: [December 16, 2020, 8:00am UTC](https://discuss.dgraph.io/t/external-ids-and-upsert-block-mutations/11926/1 "2020-12-16T08:00:56Z")

</div>

The upsert block makes managing external IDs easy.

Set the schema.

```
xid: string @index(exact) .
<http://schema.org/name>: string @index(exact) .
<http://schema.org/type>: [uid] @reverse .

```

Set the type first of all.

```
{
  set {
    _:blank <xid> "http://schema.org/Person" .
    _:blank <dgraph.type> "ExternalType" .
  }
}

```

Now you can create a new person and attach its type using the upsert block.

```
   upsert {
      query {
        var(func: eq(xid, "http://schema.org/Person")) {
          Type as uid
        }
        var(func: eq(<http://schema.org/name>, "Robin Wright")) {
          Person as uid
        }
      }
      mutation {
          set {
           uid(Person) <xid> "https://www.themoviedb.org/person/32-robin-wright" .
           uid(Person) <http://schema.org/type> uid(Type) .
           uid(Person) <http://schema.org/name> "Robin Wright" .
           uid(Person) <dgraph.type> "Person" .
          }
      }
    }

```

You can also delete a person and detach the relation between Type and Person Node. It’s the same as above, but you use the keyword “delete” instead of “set”. “`http://schema.org/Person`” will remain but “`Robin Wright`” will be deleted.

```
   upsert {
      query {
        var(func: eq(xid, "http://schema.org/Person")) {
          Type as uid
        }
        var(func: eq(<http://schema.org/name>, "Robin Wright")) {
          Person as uid
        }
      }
      mutation {
          delete {
           uid(Person) <xid> "https://www.themoviedb.org/person/32-robin-wright" .
           uid(Person) <http://schema.org/type> uid(Type) .
           uid(Person) <http://schema.org/name> "Robin Wright" .
           uid(Person) <dgraph.type> "Person" .
          }
      }
    }

```

Query by user.

```
{
  q(func: eq(<http://schema.org/name>, "Robin Wright")) {
    uid
    xid
    <http://schema.org/name>
    <http://schema.org/type> {
      uid
      xid
    }
  }
}

```

* * *
This is a companion discussion topic for the original entry at [https://dgraph.io/docs/mutations/external-ids-upsert-block/](https://dgraph.io/docs/mutations/external-ids-upsert-block/)

---

<div class="post-metadata">

### Author: ![amaster507](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amaster507/32/4123_2.png) [@amaster507](https://discuss.dgraph.io/u/amaster507)
#### Post date: [August 9, 2022, 4:17pm UTC](https://discuss.dgraph.io/t/external-ids-and-upsert-block-mutations/11926/2 "2022-08-09T16:17:15Z")

</div>

This example could be simplified quite a bit and expanded with additional details, especially for common web developers who need to user external ids (xids) but don’t really need to think about all of the weirdness of `http://schema.org/...` stuff, or for those using multiple external identifier sources.

So here is my go at rewriting this doc page:

* * *

The upsert block provides a way to mutate the graph while using external IDs (xids).

Given the schema:

```DQL
xid: string @index(exact) .
name: string @index(exact) .
starring: [uid] @reverse .
birthdate: datetime .
year: int .

type Actor {
  xid
  name
  birthdate
}

type Movie {
  xid
  name
  starring
  year
}

```

Create initial data of a movie and an actor with external identifiers (example uses imdb identifiers):

```DQL
{
  set {
    _:nm0000705 <dgraph.type> "Actor" .
    _:nm0000705 <xid> "nm0000705" .
    _:nm0000705 <name> "Robin Wright" .

    _:tt0109830 <dgraph.type> "Movie" .
    _:tt0109830 <xid> "tt0109830" .
    _:tt0109830 <name> "Forest Gump" .
  }
}

```

Then link the two nodes by external identifiers and update nodes to add additional attributes:

```DQL
upsert {
  query {
    nm0000705 as var(func: eq(xid, "nm0000705"))
    tt0109830 as var(func: eq(xid, "tt0109830"))
  }
  mutation {
    set {
      uid(tt0109830) <starring> uid(nm0000705) .
      uid(nm0000705) <birthdate> "1966-04-08" .
      uid(tt0109830) <year> "1994" .
    }
  }
}

```

You can also use an upsert block to update the xid itself.

The original data set mutation:

```DQL
{
  set {
    _:nm0000128 <dgraph.type> "Actor" .
    _:nm0000128 <xid> "nm0000128" .
    _:nm0000128 <name> "Tom Cruise" .
  }
}

```

Correct the xid using a `delete` and `set` in the same upsert mutation.

```DQL
upsert {
  query {
    nm0000128 as var(func: eq(xid, "nm0000128"))
  }
  mutation {
    delete {
      uid(nm0000128) <xid> "nm0000128" .
    }
    set {
      uid(nm0000128) <xid> "nm0000129" .
    }
  }
}

```

Note: This example uses the `S P O` delete method. For more information on delete methods see: [Overview - Dgraph](https://dgraph.io/docs/mutations/delete/)

It is possible that a singular node could have more than a singular external identifier. The important factor is that no two nodes share the same external identifer for the same predicate name. The predicate `xid` here is for an example, and could be of another name such as `uuid`. You could also use multiple predicates for unique external identifiers such as `imdb` and `rottentomatoes`

## Advance Topic: Mixing DQL external identifiers with the GraphQL API:

If using external identifiers with Dgraph’s GraphQL API, you can map the schema so all types reference the same external identifier predicate.

```GraphQL
# Dgraph's GraphQL Schema
type Movie {
  id: ID!
  xid: String! @id @dgraph(pred: "xid")
  name: String! @search(by: [exact])
  starring: [Actor] @hasInverse(field: "starringIn")
  year: Int
}

type Actor {
  id: ID!
  xid: String! @id @dgraph(pred: "xid")
  name: String! @search(by: [exact])
  starringIn: [Movie]
  birthdate: DateTime
}

```

Which would generate the following DQL schema:

```DQL
type Movie {
  xid
  Movie.name
  Movie.starring
  Movie.year
}
type Actor {
  xid
  Actor.name
  Actor.starringIn
  Actor.birthdate
}
xid: string @index(exact) .
Movie.name: string @index(exact) .
Movie.starring: [uid] .
Movie.year: int .
Actor.name: string @index(exact) .
Actor.starringIn: [uid] .
Actor.birthdate: datetime .

```

For more information on GraphQL \<\>DQL schema mapping see: [New to Dgraph? DQL vs. GraphQL, Endpoints, Headers, and Schema Translation - Users - Discuss Dgraph](http://discuss.hypermode.com/t/new-to-dgraph-dql-vs-graphql-endpoints-headers-and-schema-translation/10443?u=amaster507)
