scan query nodejs missed item example dynamodb aws all javascript amazon-web-services set amazon-dynamodb aws-lambda

javascript - query - AWS Lambda: cómo agregar números a un conjunto NS en Dynamodb



put item dynamodb lambda (2)

La cuestión

He intentado varios enfoques, pero no he podido averiguar cómo agregar números a un conjunto NS. Todo esto se ejecuta dentro de una función lambda.

Lo que intento lograr

Estoy creando una tabla dynamodb donde diferentes colores en hex se alinean con un conjunto de identificadores. Estoy optimizando la tabla para lecturas rápidas y para evitar duplicados, por lo que me gustaría mantener un conjunto de identificadores para cada hex.

Cómo estoy agregando elementos a la mesa:

let doc = require(''dynamodb-doc''); let dynamo = new doc.DynamoDB(); var object = { ''TableName'': ''Hex'', ''Item'': { ''hex'': ''#FEFEFE'', ''ids'': { ''NS'': [2,3,4] } } } dynamo.putItem(object, callback);

Lo que resulta en

Luego trato de agregar más identificadores al conjunto

Uso de los estándares de documentación de elementos de actualización de Dynamodb

var params = { "TableName" : "Hex", "Key": { "hex": "#FEFEFE" }, "UpdateExpression" : "ADD #oldIds :newIds", "ExpressionAttributeNames" : { "#oldIds" : "ids" }, "ExpressionAttributeValues": { ":newIds" : {"NS": ["5", "6"]} }, }; dynamo.updateItem(params, callback);

Esto devuelve el siguiente error, por lo que dynamo piensa: newIds es un tipo de mapa en lugar de un conjunto (?)

"errorMessage": "Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: MAP"

También he probado estos enfoques alternativos

Prueba 2:

var setTest = new Set([5, 6]); var params = { "TableName" : "Hex", "Key": { "hex": "#FEFEFE" }, "UpdateExpression" : "ADD #oldIds :newIds", "ExpressionAttributeNames" : { "#oldIds" : "ids" }, "ExpressionAttributeValues": { ":newIds" : setTest }, }; dynamo.updateItem(params, callback);

Error 2 (mismo error):

"errorMessage": "Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: MAP"

Prueba 3:

var params = { "TableName" : "Hex", "Key": { "hex": "#FEFEFE" }, "UpdateExpression" : "ADD #oldIds :newIds", "ExpressionAttributeNames" : { "#oldIds" : "ids" }, "ExpressionAttributeValues": { ":newIds" : { "NS" : { "L" : [ { "N" : "5" }, { "N" : "6" } ] }} }, }; dynamo.updateItem(params, callback);

Error 3 (mismo error):

"errorMessage": "Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: MAP"

Prueba 4:

var params = { "TableName" : "Hex", "Key": { "hex": "#FEFEFE" }, "UpdateExpression" : "ADD #oldIds :newIds", "ExpressionAttributeNames" : { "#oldIds" : "ids" }, "ExpressionAttributeValues": { ":newIds" : [5,6] }, }; dynamo.updateItem(params, callback);

Error 4 (error similar, pero Dynamo cree que estoy agregando una lista esta vez)

"errorMessage": "Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: LIST"

Stack Overflow / Github Preguntas que he probado

https://stackoverflow.com/a/37585600/4975772 (estoy agregando un conjunto, no una lista)

https://stackoverflow.com/a/37143879/4975772 (estoy usando javascript, no python, pero básicamente necesito lo mismo con una sintaxis diferente)

https://github.com/awslabs/dynamodb-document-js-sdk/issues/40#issuecomment-123003444 (Necesito hacer esto exactamente, pero no estoy usando el dynamodb-document-js-sdk, Estoy usando AWS Lambda


He estado luchando con esto también. Descubrí que en realidad hay 2 API para DynamoDB.

AWS.DynamoDB

AWS.DynamoDBDocumentClient

Al igual que usted, no pude hacer funcionar la función ADD. Intenté importar y usar la api DynamoDB en lugar de la api DynamoDBDocumentClient. Me solucionó el problema. A continuación se muestra mi fragmento de código que funciona con la API DynamoDB pero no con la API DynamoDBDocumentClient. Uso un conjunto de cuerdas en lugar de un conjunto de números, pero eso no supondrá una diferencia, supongo.

var AWS = require(''aws-sdk''); var dynamo = new AWS.DynamoDB(); // var dynamo = new AWS.DynamoDB.DocumentClient(); ... var params = {}; params.TableName = “MyTable”; params.ExpressionAttributeValues = { '':newIds'': { "SS": ["someId"] } }; // :newIds represents a new dynamodb set with 1 element params.UpdateExpression = "ADD someAttribute :newIds"; dynamoClient.updateItem(params, function(err, data) { ….}


La respuesta de Peter Fennema es totalmente correcta. Solo quiero exponer por qué el original estaba fallando y mostrar la respuesta formateada como el original.

Hizo algo más de excavación, el problema central es en realidad cuando se crea el conjunto original. Pero como dijo Fennema, podemos usar la nueva API , lanzada en septiembre de 2015, para evitar el problema por completo. De acuerdo con el documento de lanzamiento, aquí está el

Forma correcta de crear un conjunto y agregar elementos a un conjunto

let AWS = require(''aws-sdk''); let docClient = new AWS.DynamoDB.DocumentClient(); ... var params = { TableName : ''Hex'', Key: {''hex'': ''#FEFEFE''}, UpdateExpression : ''ADD #oldIds :newIds'', ExpressionAttributeNames : { ''#oldIds'' : ''ids'' }, ExpressionAttributeValues : { '':newIds'' : docClient.createSet([1,2]) } }; docClient.update(params, callback);

Lo que resulta en esta tabla de dynamodb:

Si el conjunto no existe, entonces ese código lo creará para usted. También puede ejecutar ese código con un conjunto diferente para actualizar los elementos del conjunto. Súper conveniente.

Por qué el original estaba fallando

Observe cómo cuando hice la pregunta, el conjunto resultante parecía un objeto de mapa literal json (cuando se veía en la captura de pantalla de dynamodb), lo que explicaría este mensaje de error

"errorMessage": "Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: MAP"

Así que estaba usando la sintaxis incorrecta. La solución se encuentra en los (ahora privados) AWS Labs dynamodb-document-js-sdk docs

let doc = require(''dynamodb-doc''); let dynamo = new doc.DynamoDB(); var params = { TableName : ''Hex'', Key: {''hex'': ''#555555''}, UpdateExpression : ''ADD #oldIds :newIds'', ExpressionAttributeNames : { ''#oldIds'' : ''ids'' }, ExpressionAttributeValues : { '':newIds'' : dynamo.Set([2,3], ''N'') } }; dynamo.updateItem(params, callback);

(No use este código para futuros desarrollos, solo lo incluyo para ayudar a cualquiera que use el DynamoDB Document SDK existente)

La documentación completa para el nuevo Document Client se puede ver aquí: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html