在Node中使用DynamoDB.DocumentClient检索StringSet值

eqqqjvef  于 2023-10-17  发布在  Node.js
关注(0)|答案(2)|浏览(90)

DynamoDB.DocumentClient自动封送和反封送JavaScript类型之间的值,DynamoDB的AttributeMap类型更具描述性。但是,当使用具有StringSet属性的Item时,它似乎不会自动进行转换。
当使用DocumentClient向表中添加StringSet属性时,我使用createSet(...)方法将数组转换为Set。当检索回值时,createSet(...)的逆是什么?最佳做法是直接访问Set的.values吗?如果是的话,有没有记录在案呢?
下面是添加一个具有StringSet属性的Item,然后检索该Item的示例代码:

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(...)的同一个数组。
如果有兴趣看到这个活动,this repo has a fully-functioning example.克隆它,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
oug3syen

oug3syen1#

我这里的最佳解决方案是避免使用DocumentClientcreateSet(...)方法。下面是一个使用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's Converter模块中的marshall/unmarshall方法可以类似地工作。

egdjgwm8

egdjgwm82#

这不是封送处理问题,字符串集的顺序未定义:
此处记录:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes

不保留集合内值的顺序。

相关问题