首页 > 解决方案 > 在 UpdateExpression 上使用 DELETE Set 更新 DynamoDB 记录失败并出现 node.js

问题描述

我正在尝试使用下面代码片段上的有效负载对DynamoDB.DocumentClient实例执行更新调用:AWS SDK

const AWS = require('aws-sdk')
const DynamoDB = new AWS.DynamoDB.DocumentClient()
...

const TableName = 'MyTable'
const Key = { PK: 'MyPK', SK: 'MySK' }
const operation = 'DELETE'
const myId = 'abcde'
const currentRecord = await DynamoDB.get({TableName, Key)

DynamoDB.update({
      TableName,
      Key,
      UpdateExpression: `
        ${operation} myIds :valuesToModify,
        version :incrementVersionBy
      `,
      ConditionExpression: `version = :version`,
      ExpressionAttributeValues: {
        ":version": currentRecord.version,
        ":incrementVersionBy": 1,
        ":valuesToModify": DynamoDB.createSet([myId])
      }
})...

结果我收到此错误:

ERROR Invoke Error 
{
  "errorType":"Error",
  "errorMessage":"ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function;
   operator: DELETE, operand type: NUMBER, typeSet: ALLOWED_FOR_DELETE_OPERAND",
  "stack":[...]
}

有趣的是,如果operation更改为ADD它运行良好。

非常感谢任何有助于理解为什么ADD有效和无效的线索DELETE和/或如何修复和/或与此更新操作兼容的替代方法!

标签: node.jsamazon-dynamodbsetaws-sdkaws-sdk-nodejs

解决方案


这里唯一可能的解决方法是不使用 DELETE 操作,相反,您必须查询该项目,在要删除的数组中找到索引,然后使用 REMOVE 操作将其删除:

就像在这种情况下,arrayField 包含一个用户数组,我想通过用户的电话号码删除。

const dataStore = await dynamodb.get(queryParams).promise();
    let i=0; //save the index
    for(i = 0; i < dataStore.Item.myTable.length; i++){
      if(dataStore.Item.arrayField[i].phone === phoneNumber)
      {
        break;
      }
    }
    if(i < dataStore.Item.arrayField.length){
        const updateStoreParams = {
            TableName: tableName,
            Key: storeTableKey,
            UpdateExpression: `REMOVE arrayField[${i}]`,
        }
        await dynamodb.update(updateStoreParams).promise().catch((err) => {
            console.log(err); 
            throw err;
            });
    }

推荐阅读