Skip to content

Commit

Permalink
Add docs for Upsert Block (dgraph-io#3412)
Browse files Browse the repository at this point in the history
  • Loading branch information
mangalaman93 authored and dna2github committed Jul 19, 2019
1 parent 2297363 commit 45b1e55
Showing 1 changed file with 149 additions and 0 deletions.
149 changes: 149 additions & 0 deletions wiki/content/mutations/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -778,3 +778,152 @@ Mutation with a JSON file:
```sh
curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d @data.json
```

## Upsert Block

The Upsert block allows performing queries and mutations in a single request. The Upsert
block contains one query block and one mutation block. Variables defined in the
query block can be used in the mutation block using the `uid` function.

In general, the structure of the Upsert block is as follows:

```
upsert {
query <query block>
[fragment <fragment block>]
mutation <mutation block>
}
```

The Mutation block currently only allows the `uid` function, which allows extracting UIDs
from variables defined in the query block. There are 3 possible outcomes based on the
results of executing the query block:
* If the variable is empty i.e. has no value, the `uid` function returns a new UID and
is treated similar to a blank node.
* If the variable stores exactly one UID, the `uid` function returns the uid stored in
the variable.
* If the variable stores more than one UID, the mutation fails. We plan to support
this use case in the future.

### Example

Consider an example with following schema:

```sh
curl localhost:8080/alter -X POST -d $'
name: string @index(term) .
email: string @index(exact) @upsert .
age: int @index(int) .
friend: uid @reverse .
' | jq
```

### Insert Use Case

Now, let's say we want to create a new user with `email`, and `name` information.
We also want to make sure that two users cannot have same email id in the database.
We can do this using the Upsert block as follows:

```sh
curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $'
upsert {
query {
me(func: eq(email, "[email protected]")) {
v as uid
}
}
mutation {
set {
uid(v) <name> "first last" .
uid(v) <email> "[email protected]" .
}
}
}
' | jq
```

Result:

```json
{
"data": {
"code": "Success",
"message": "Done",
"uids": {
"uid(v)": "0x2"
}
},
"extensions": {
"server_latency": {
"parsing_ns": 71033,
"processing_ns": 22994018
},
"txn": {
"start_ts": 4,
"commit_ts": 5,
"preds": [
"1-email",
"1-name"
]
}
}
}
```

The upsert first checks whether a user with the email `[email protected]` exists. Because
the database is currently empty, no such user exists. Hence, the variable `v` will be
empty. In this case, the `uid` function returns a new UID for the variable `v` replacing
with the new UID value wherever `uid(v)` is used.

### Update Use Case

Now, we want to add the `age` information for the same user having email ID
`[email protected]`. We can use the Upsert block to do the same as follows:

```sh
curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $'
upsert {
query {
me(func: eq(email, "[email protected]")) {
v as uid
}
}
mutation {
set {
uid(v) <age> "28" .
}
}
}
' | jq
```

Result:

```json
{
"data": {
"code": "Success",
"message": "Done",
"uids": {}
},
"extensions": {
"server_latency": {
"parsing_ns": 39017,
"processing_ns": 21231954
},
"txn": {
"start_ts": 7,
"commit_ts": 8,
"preds": [
"1-age"
]
}
}
}
```

Here, the query block queries for a user with `email` as `[email protected]`. It stores the
`uid` of the user in variable `v`. The mutation block then updates the `age` of the
user. The `uid` function extracts the uid from the variable `v`.

0 comments on commit 45b1e55

Please sign in to comment.