

# Usar expressões de atualização no DynamoDB
<a name="Expressions.UpdateExpressions"></a>

A ação `UpdateItem` atualiza um item existente ou adiciona um item novo à tabela, caso ele ainda não exista. Você deve fornecer a chave do item que deseja atualizar. Você também deve fornecer uma expressão de atualização indicando os atributos que deseja modificar e os valores que deseja atribuir a eles. 

Uma *expressão de atualização* especifica como `UpdateItem` modificará os atributos de um item. Por exemplo, definindo um valor escalar ou removendo elementos de uma lista ou de um mapa.

Veja a seguir um resumo da sintaxe para expressões de atualização.

```
update-expression ::=
    [ SET action [, action] ... ]
    [ REMOVE action [, action] ...]
    [ ADD action [, action] ... ]
    [ DELETE action [, action] ...]
```

Uma expressão de atualização consiste em uma ou mais cláusulas. Cada cláusula começa com uma palavra-chave `SET`, `REMOVE`, `ADD` ou `DELETE`. Você pode incluir qualquer uma dessas cláusulas em uma expressão de atualização, em qualquer ordem. No entanto, cada palavra-chave de ação pode aparecer apenas uma vez.

Dentro de cada cláusula há uma ou mais ações, separadas por vírgulas. Cada ação representa uma modificação de dados.

Os exemplos desta seção se baseiam no item `ProductCatalog` mostrado em [Usar expressões de projeção no DynamoDB](Expressions.ProjectionExpressions.md).

Os tópicos abaixo abrangem alguns casos de uso diferentes da ação `SET`.

**Topics**
+ [SET: modificar ou adicionar atributos de um item](#Expressions.UpdateExpressions.SET)
+ [REMOVE: excluir atributos de um item](#Expressions.UpdateExpressions.REMOVE)
+ [ADD: atualizar números e conjuntos](#Expressions.UpdateExpressions.ADD)
+ [DELETE: remover elementos de um conjunto](#Expressions.UpdateExpressions.DELETE)
+ [Usar várias expressões de atualização](#Expressions.UpdateExpressions.Multiple)

## SET: modificar ou adicionar atributos de um item
<a name="Expressions.UpdateExpressions.SET"></a>

Use a ação `SET` em uma expressão de atualização para adicionar um ou mais atributos a um item. Se qualquer um desses atributos já existir, eles serão substituídos pelos novos valores. Se você deseja evitar a substituição de um atributo existente, pode usar `SET` com a função `if_not_exists`. A função `if_not_exists` é específica à ação `SET` e só pode ser usada em uma expressão de atualização.

Quando você usa `SET` para atualizar um elemento de lista, o conteúdo desse elemento é substituído pelos novos dados especificados. Se o elemento ainda não existir, `SET` acrescentará o novo elemento ao final da lista.

Se você adicionar vários elementos em uma única operação `SET`, estes serão classificados por número de elemento.

Você também pode usar `SET` para adicionar ou subtrair de um atributo do tipo `Number`. Para executar várias ações `SET`, separe-as com vírgulas.

No seguinte resumo de sintaxe:
+ O elemento *path* é o caminho do documento para o item.
+ Um elemento **operando** pode ser o caminho de um documento para um item ou uma função.

```
set-action ::=
    path = value

value ::=
    operand
    | operand '+' operand
    | operand '-' operand

operand ::=
    path | function

function ::=
    if_not_exists (path, value)
```

Se o item não contiver um atributo no caminho especificado, `if_not_exists` será avaliado como `value`. Caso contrário, será avaliado como `path`.

A seguinte operação `PutItem` cria um item de exemplo ao qual os exemplos fazem referência.

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json
```

Os argumentos de `--item` são armazenados no arquivo `item.json`. (Para simplificar, apenas alguns atributos de item são usados.)

```
{
    "Id": {"N": "789"},
    "ProductCategory": {"S": "Home Improvement"},
    "Price": {"N": "52"},
    "InStock": {"BOOL": true},
    "Brand": {"S": "Acme"}
}
```

**Topics**
+ [Modificar atributos](#Expressions.UpdateExpressions.SET.ModifyingAttributes)
+ [Adicionar listas e mapas](#Expressions.UpdateExpressions.SET.AddingListsAndMaps)
+ [Adicionar elementos a uma lista](#Expressions.UpdateExpressions.SET.AddingListElements)
+ [Adicionar atributos de mapa aninhados](#Expressions.UpdateExpressions.SET.AddingNestedMapAttributes)
+ [Incrementar e reduzir atributos numéricos](#Expressions.UpdateExpressions.SET.IncrementAndDecrement)
+ [Acrescentar elementos a uma lista](#Expressions.UpdateExpressions.SET.UpdatingListElements)
+ [Impedir substituições de um atributo existente](#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites)

### Modificar atributos
<a name="Expressions.UpdateExpressions.SET.ModifyingAttributes"></a>

**Example**  
Atualize os atributos `ProductCategory` e `Price`.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET ProductCategory = :c, Price = :p" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":c": { "S": "Hardware" },
    ":p": { "N": "60" }
}
```

**nota**  
Na operação `UpdateItem`, `--return-values ALL_NEW` faz com que o DynamoDB retorne o item como ele aparece após a atualização.

### Adicionar listas e mapas
<a name="Expressions.UpdateExpressions.SET.AddingListsAndMaps"></a>

**Example**  
Adicione uma nova lista e um novo mapa.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems = :ri, ProductReviews = :pr" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":ri": {
        "L": [
            { "S": "Hammer" }
        ]
    },
    ":pr": {
        "M": {
            "FiveStar": {
                "L": [
                    { "S": "Best product ever!" }
                ]
            }
        }
    }
}
```

### Adicionar elementos a uma lista
<a name="Expressions.UpdateExpressions.SET.AddingListElements"></a>

**Example**  
Adicione um novo atributo à lista `RelatedItems`. (Lembre-se de que elementos de lista são baseados em zero e, portanto, [0] representa o primeiro elemento da lista, [1] representa o segundo, e assim por diante.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :ri" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":ri": { "S": "Nails" }
}
```

**nota**  
Quando você usa `SET` para atualizar um elemento de lista, o conteúdo desse elemento é substituído pelos novos dados especificados. Se o elemento ainda não existir, `SET` acrescentará o novo elemento ao final da lista.  
Se você adicionar vários elementos em uma única operação `SET`, estes serão classificados por número de elemento.

### Adicionar atributos de mapa aninhados
<a name="Expressions.UpdateExpressions.SET.AddingNestedMapAttributes"></a>

**Example**  
Adicione alguns atributos de mapa aninhados.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #pr.#5star[1] = :r5, #pr.#3star = :r3" \
    --expression-attribute-names file://names.json \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-names` são armazenados no arquivo `names.json`.  

```
{
    "#pr": "ProductReviews",
    "#5star": "FiveStar",
    "#3star": "ThreeStar"
}
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":r5": { "S": "Very happy with my purchase" },
    ":r3": {
        "L": [
            { "S": "Just OK - not that great" }
        ]
    }
}
```

**Importante**  
Não será possível atualizar os atributos do mapa aninhado se o mapa pai não existir. Se você tentar atualizar um atributo aninhado (por exemplo, `ProductReviews.FiveStar`) quando o mapa pai (`ProductReviews`) não existir, o DynamoDB exibirá `ValidationException` com a mensagem *“O caminho do documento fornecido na expressão de atualização é inválido para atualização”*.  
Ao criar itens que terão atributos de mapa aninhados atualizados posteriormente, inicialize mapas vazios para os atributos principais. Por exemplo:  

```
{
    "Id": {"N": "789"},
    "ProductReviews": {"M": {}},
    "Metadata": {"M": {}}
}
```
Isso permite que você atualize atributos aninhados, como `ProductReviews.FiveStar`, sem erros.

### Incrementar e reduzir atributos numéricos
<a name="Expressions.UpdateExpressions.SET.IncrementAndDecrement"></a>

Você pode adicionar ou subtrair de um atributo numérico existente. Para fazer isso, use os operadores `+` (mais) e `-` (menos).

**Example**  
Diminua o valor do `Price` de um item.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```
Para aumentar o valor do `Price`, você usa o operador `+` na expressão de atualização.

### Acrescentar elementos a uma lista
<a name="Expressions.UpdateExpressions.SET.UpdatingListElements"></a>

É possível adicionar elementos ao final de uma lista. Para fazer isso, use `SET` com a função `list_append`. (O nome da função diferencia maiúsculas de minúsculas.) A função `list_append` é específica à ação `SET` e só pode ser usada em uma expressão de atualização. A sintaxe é a seguinte.
+ `list_append (list1, list2)`

A função utiliza duas listas como entrada e acrescenta todos os elementos de `list2` a ` list1`.

**Example**  
Em [Adicionar elementos a uma lista](#Expressions.UpdateExpressions.SET.AddingListElements), você cria a lista `RelatedItems` e a preenche com dois elementos: `Hammer` e `Nails`. Na sequência, você acrescenta mais dois elementos ao final de `RelatedItems`.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(#ri, :vals)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values file://values.json  \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":vals": {
        "L": [
            { "S": "Screwdriver" },
            {"S": "Hacksaw" }
        ]
    }
}
```
Por fim, você acrescenta mais um elemento ao *início* de `RelatedItems`. Para fazer isso, alterne a ordem dos elementos de `list_append`. (Lembre-se de que `list_append` usa duas listas como entrada e acrescenta a segunda lista à primeira.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(:vals, #ri)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values '{":vals": {"L": [ { "S": "Chisel" }]}}' \
    --return-values ALL_NEW
```
Agora, o atributo `RelatedItems` resultante contém cinco elementos, na seguinte ordem: `Chisel`, `Hammer`, `Nails`, `Screwdriver`, `Hacksaw`.

### Impedir substituições de um atributo existente
<a name="Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites"></a>

**Example**  
Defina o `Price` de um item, mas somente se o item ainda não tiver um atributo `Price`. (Se o atributo `Price` já existir, não acontecerá nada.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = if_not_exists(Price, :p)" \
    --expression-attribute-values '{":p": {"N": "100"}}' \
    --return-values ALL_NEW
```

## REMOVE: excluir atributos de um item
<a name="Expressions.UpdateExpressions.REMOVE"></a>

Use a ação `REMOVE` em uma expressão de atualização para remover um ou mais atributos de um item no Amazon DynamoDB. Para executar várias ações `REMOVE`, separe-as com vírgulas.

O seguinte é um resumo da sintaxe de `REMOVE` em uma expressão de atualização. O único operando é o caminho do documento do atributo que você deseja remover.

```
remove-action ::=
    path
```

**Example**  
Remova alguns atributos de um item. (Se os atributos não existirem, nada acontecerá.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE Brand, InStock, QuantityOnHand" \
    --return-values ALL_NEW
```

### Remover elementos de uma lista
<a name="Expressions.UpdateExpressions.REMOVE.RemovingListElements"></a>

É possível usar `REMOVE` para excluir elementos individuais de uma lista.

**Example**  
Em [Acrescentar elementos a uma lista](#Expressions.UpdateExpressions.SET.UpdatingListElements), você modifica um atributo da lista (`RelatedItems`) de forma que ele contenha cinco elementos:   
+ `[0]`—`Chisel`
+ `[1]`—`Hammer`
+ `[2]`—`Nails`
+ `[3]`—`Screwdriver`
+ `[4]`—`Hacksaw`
O exemplo da AWS Command Line Interface (AWS CLI) a seguir exclui `Hammer` e `Nails` da lista.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE RelatedItems[1], RelatedItems[2]" \
    --return-values ALL_NEW
```
Depois que `Hammer` e `Nails` forem removidos, os elementos restantes serão deslocados. Agora, a lista contém o seguinte:  
+ `[0]`—`Chisel`
+ `[1]`—`Screwdriver`
+ `[2]`—`Hacksaw`

## ADD: atualizar números e conjuntos
<a name="Expressions.UpdateExpressions.ADD"></a>

**nota**  
Em geral, recomendamos usar `SET` em vez de `ADD` para garantir operações idempotentes.

Use a ação `ADD` em uma expressão de atualização para adicionar um novo atributo e seus valores a um item.

Se o atributo já existir, o comportamento de `ADD` dependerá do tipo de dados do atributo:
+ Se o atributo for um número, e o valor que você está adicionando também for um número, esse valor será matematicamente adicionado ao atributo existente. (Se o valor for um número negativo, ele será subtraído do atributo existente.)
+ Se o atributo for um conjunto, e o valor que você está adicionando também for um conjunto, esse valor será acrescentado ao conjunto existente.

**nota**  
A ação `ADD` oferece suporte apenas a tipos de dados de número e conjunto.

Para executar várias ações `ADD`, separe-as com vírgulas.

No seguinte resumo de sintaxe:
+ O elemento *path* é o caminho do documento para um atributo. O atributo deve ser um `Number` ou um tipo de dados de conjunto. 
+ O elemento *value* é um número que você deseja adicionar ao atributo (para tipos de dados `Number`) ou um conjunto a ser acrescentado ao atributo (para tipos de conjunto).

```
add-action ::=
    path value
```

Os tópicos abaixo abrangem alguns casos de uso diferentes da ação `ADD`.

**Topics**
+ [Adicionar um número](#Expressions.UpdateExpressions.ADD.Number)
+ [Adicionar elementos a um conjunto](#Expressions.UpdateExpressions.ADD.Set)

### Adicionar um número
<a name="Expressions.UpdateExpressions.ADD.Number"></a>

Suponha que o atributo `QuantityOnHand` não exista. O exemplo da AWS CLI a seguir define `QuantityOnHand` como 5.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD QuantityOnHand :q" \
    --expression-attribute-values '{":q": {"N": "5"}}' \
    --return-values ALL_NEW
```

Agora que `QuantityOnHand` existe, você pode executar novamente o exemplo para incrementar `QuantityOnHand` em 5 de cada vez.

### Adicionar elementos a um conjunto
<a name="Expressions.UpdateExpressions.ADD.Set"></a>

Suponha que o atributo `Color` não exista. O exemplo da AWS CLI a seguir define `Color` como um conjunto de strings com dois elementos.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Orange", "Purple"]}}' \
    --return-values ALL_NEW
```

Agora que `Color` existe, você pode adicionar mais elementos a ele.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Yellow", "Green", "Blue"]}}' \
    --return-values ALL_NEW
```

## DELETE: remover elementos de um conjunto
<a name="Expressions.UpdateExpressions.DELETE"></a>

**Importante**  
A ação `DELETE` oferece suporte apenas a tipos de dados `Set`.

Use a ação `DELETE` em uma expressão de atualização para remover um ou mais elementos de um conjunto. Para executar várias ações `DELETE`, separe-as com vírgulas.

No seguinte resumo de sintaxe:
+ O elemento *path* é o caminho do documento para um atributo. Esse atributo deve ser um tipo de dados de conjunto.
+ O elemento *subset* é um ou mais elementos que você deseja excluir de *path*. Você deve especificar o elemento *subset* como um tipo set.

```
delete-action ::=
    path subset
```

**Example**  
Em [Adicionar elementos a um conjunto](#Expressions.UpdateExpressions.ADD.Set), você cria o conjunto de tipo string `Color`. Este exemplo remove alguns dos elementos desse conjunto.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "DELETE Color :p" \
    --expression-attribute-values '{":p": {"SS": ["Yellow", "Purple"]}}' \
    --return-values ALL_NEW
```

## Usar várias expressões de atualização
<a name="Expressions.UpdateExpressions.Multiple"></a>

É possível usar várias ações em uma única expressão de atualização. Todas as referências a atributos são resolvidas em relação ao estado do item antes que qualquer uma das ações seja aplicada.

**Example**  
Dado um item `{"id": "1", "a": 1, "b": 2, "c": 3}`, a seguinte expressão remove `a` e muda os valores de `b` e `c`:  

```
aws dynamodb update-item \
    --table-name test \
    --key '{"id":{"S":"1"}}' \
    --update-expression "REMOVE a SET b = a, c = b" \
    --return-values ALL_NEW
```
O resultado é `{"id": "1", "b": 1, "c": 2}`. Embora `a` seja removida e `b` reatribuída na mesma expressão, ambas as referências retornam os valores originais.

**Example**  
Se quiser modificar o valor de um atributo e remover outro completamente, você poderá usar uma ação SET e uma REMOVE em uma única declaração. Essa operação reduziria o valor de `Price` para 15 e, ao mesmo tempo, removeria o atributo `InStock` do item.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p REMOVE InStock" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```

**Example**  
Se quiser adicionar a uma lista e, ao mesmo tempo, alterar o valor de outro atributo, você poderá usar duas ações SET em uma única declaração. Essa operação adicionaria “Unhas” ao atributo da lista `RelatedItems` e também definiria o valor de `Price` como 21.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :newValue, Price = :newPrice" \
    --expression-attribute-values '{":newValue": {"S":"Nails"}, ":newPrice": {"N":"21"}}'  \
    --return-values ALL_NEW
```