如何编写参数以更新数组对象中特定属性的值?

时间:2019-09-11 15:12:19

标签: node.js aws-lambda documentclient

如何根据电影数组中的标题和商品ID(123)更新数量值

我只设法更新第一层的值,例如名称(David),但不知道如何使用数组(电影)的附加过滤器更新第二层。

发件人:

Item:
{
   id: 123,
   name: 'David',
   movies: [
      {
         id: 1,
         title: 'The lord of the ring',
         quantity: 1
      },
      {
         id: 2,
         title: 'Star Wars',
         quantity: 1
      }
   ]
}

收件人:

Item:
{
   id: 123,
   Name: 'David',
   movies: [
      {
         id: 1,
         title: 'The lord of the ring',
         quantity: 2
      },
      {
         id: 2,
         title: 'Star Wars',
         quantity: 1
      }
   ]
}

顺便说一句,我在node.js中使用aws DynamoDB文档客户端,如果您可以在更新参数中与我分享您的操作方式,那就太好了。

2 个答案:

答案 0 :(得分:0)

如果不替换列表,则无法更新列表中的对象。

您可能想要重组表以模拟关系数据模型。 AWS对此有some documentation

例如,创建您的表,如下所示:

aws dynamodb create-table \
  --table-name movie-table \
  --attribute-definitions AttributeName=rId,AttributeType=N AttributeName=rKey,AttributeType=S \
  --key-schema AttributeName=rId,KeyType=HASH AttributeName=rKey,KeyType=RANGE

该表将具有通用名称的哈希键和范围键。该脚本演示了如何构造数据并添加到“计数”中:

const { DynamoDB } = require('aws-sdk');

const client = new DynamoDB.DocumentClient({ region: 'us-east-1' });

const addItem = (rId, rKey, attributes) => {
  const item = { rId, rKey };
  Object.assign(item, attributes);
  return client.put({ TableName: 'movie-table', Item: item }).promise();
};

// NOTE: this is where the count attribute gets iterated
const addToCount = (rId, rKey) => client.update({
  TableName: 'movie-table',
  Key: { rId, rKey },
  UpdateExpression: 'ADD #count :n',
  ExpressionAttributeNames: { '#count': 'count' },
  ExpressionAttributeValues: { ':n': 1 },
}).promise();

const run = async () => {
  await addItem(123, 'USER|123', { name: 'David' });
  await addItem(1, 'MOVIE|1', { title: 'The lord of the ring' });
  await addItem(2, 'MOVIE|2', { title: 'Star Wars' });
  await addItem(123, 'COUNT|1', { count: 1 });
  await addItem(123, 'COUNT|2', { count: 1 });
  await addToCount(123, 'COUNT|1');
};

run();

脚本运行后,表的外观如下:

enter image description here

答案 1 :(得分:0)

我知道这有点老了,但是有办法。使用文档客户端SDK,可以在UpdateExpression中引用对象属性和数组元素。但是,您无法运行任何逻辑,因此您必须知道/假设/期望元素索引足够。

例如,您可以执行以下操作:

    let params = {
         TableName: 'your-table-name',
         Key: { id: 123 },
         UpdateExpression: 'set movies[0].quantity = :x',
         ExpressionAttributeValues: { ':x': 5 }
     };

     const client = AWS.DynamoDB.DocumentClient();

     client.update(params);

注意:您不能使索引成为表达式属性值。您将必须基于您知道必须更新的索引来动态构建该更新表达式。这不是一个完美的解决方案,但可以完成工作。

作为参考,我从下面的基础(非DocumentClient)示例中派生了此内容:Adding Nested Map Attributes