6

JavaScript 类型之间的DynamoDB.DocumentClient自动编组和解组值是 DynamoDB 更具描述性的AttributeMap类型。但是,当使用具有StringSet属性的 Item 时,它似乎不会自动进行转换。

使用 向表添加StringSet属性时DocumentClient,我使用该createSet(...)方法将数组转换为 Set。取回值时, 的倒数是createSet(...)什么?直接访问 Set 的最佳做法是.values什么?如果是这样,是否记录在某处?

这是添加具有StringSet属性的项目的示例代码,然后检索该项目:

    const docClient = new DocumentClient();
    const TableName = "StringSets-Example";
    const PK = "Names";
    const Values = ["Peter", "Paul", "Mary"];

    const putParams = {
        TableName,
        Item: {
            PK,
            names: docClient.createSet(Values)
        }
    }
    await docClient.put(putParams).promise();

    // ... some time later, I can retrieve the value with ...

    const getParams = {
        TableName,
        Key: { PK }
    }
    const result = await docClient.get(getParams).promise();

result.Item一个Set对象,而我希望它是我传入的同一个数组createSet(...)

如果有兴趣看到这个现场,这个 repo 有一个功能齐全的例子。 克隆它,npm install然后运行index.js,你会看到如下内容:

 $ ./index.js 
Running On: darwin 19.6.0
Node version: v12.20.0
AWS SDK version: 2.799.0
-------------------------
Creating table "StringSets-Example"
Waiting for "StringSets-Example" status to be "ACTIVE"
  Table status is: CREATING
  Table status is: ACTIVE
Put String Set "["Peter, "Paul, "Mary"]" into "StringSets-Example" with key "Names" and attribute "names"
Retrieved Item with key "Names" from "StringSets-Example"
The raw Item:  {
  PK: 'Names',
  names: Set {
    wrapperName: 'Set',
    values: [ 'Mary', 'Paul', 'Peter' ],
    type: 'String'
  }
}
The raw Item.names.values: [ 'Mary', 'Paul', 'Peter' ]
-------------------------
Done.  To clean up, run:
    ./src/deleteTable.js
4

1 回答 1

1

我在这里最好的解决方案是避免使用DocumentClientandcreateSet(...)方法。这是使用AWS SDK V3的示例:

const key = { PK: `SampleNames`, SK: `SampleNames` };
const names = new Set([`Peter`, `Paul`, `Mary`]);
const item = { ...key, names };
const marshalledItem = marshall(item);

console.log(`Raw item: ${inspect(item)}`)
console.log(`Marshalled item to PUT: ${inspect(marshalledItem, { depth: 4 })}`)
const client = new DynamoDBClient({});
await client.send(new PutItemCommand({
    TableName: tableName,
    Item: marshalledItem,
}));

const { Item } = await client.send(new GetItemCommand({
    TableName: tableName,
    Key: marshall(key),
}));

console.log(`Returned item: ${inspect(Item, { depth: 4 })}`);
console.log(`Unmarshalled returned item: ${inspect(unmarshall(Item))}`);

那里的控制台输出是:

Raw item: {
  PK: 'SampleNames',
  SK: 'SampleNames',
  names: Set { 'Peter', 'Paul', 'Mary' }
}
Marshalled item to PUT: {
  PK: { S: 'SampleNames' },
  SK: { S: 'SampleNames' },
  names: { SS: [ 'Peter', 'Paul', 'Mary' ] }
}
Returned item: {
  PK: { S: 'SampleNames' },
  SK: { S: 'SampleNames' },
  names: { SS: [ 'Mary', 'Paul', 'Peter' ] }
}
Unmarshalled returned item: {
  PK: 'SampleNames',
  SK: 'SampleNames',
  names: Set { 'Mary', 'Paul', 'Peter' }
}

...这对我来说更有意义。我希望使用AWS SDK V2 的 Convertermarshall模块中的/unmarshall方法可以类似地工作。

于 2020-12-19T19:47:39.520 回答