DynamoDB:如何从属性值读取实际字段值?



我正在使用用java编写的AWS Lambda来处理DynamoDB Streams。 这是代码:

public class DDBEventProcessor implements
RequestHandler<DynamodbEvent, String> {
public String handleRequest(DynamodbEvent ddbEvent, Context context) {
for (DynamodbStreamRecord record : ddbEvent.getRecords()){
Map<String, AttributeValue> tmp = record.getDynamodb.getNewImage();   

//convert tmp to Map<String, Object> here
}
}
}

我需要进一步处理记录。

为此,需要将其转换为Map<String, Object>.
接收的数据格式为:{ "id":{"s":"777"}}.
但我想将其转换为{"id":"777"},以便我能够轻松解析地图对象。但是也有嵌套数组和映射。此外,记录非常复杂,由嵌套数组和映射组成。如何实现这一点?

我知道你想将Map<String, AttributeValue>转换为Map<String, Object>,所以如果你想要"对象",@knittl回答是正确的,但你想获取每个字段的文字值,而不是简单地将AttributeValue转换为Object,如果我理解正确的话。

因此,如果您签出AttributeValue的代码:

public class AttributeValue implements Serializable, Cloneable {
private String s;
private String n;
private ByteBuffer b;
private List<String> sS;
private List<String> nS;
private List<ByteBuffer> bS;
private Map<String, AttributeValue> m;
private List<AttributeValue> l;
private Boolean nULLValue;
private Boolean bOOL;
...

您可以看到列出了许多类型字段,它们用于强制"键入"。我们将回到这个问题.
因为您将其作为 DynamoDB 流事件获得,所以我们需要一个模型类,我们可以讨论:)

假设我们有这个简单的模型类:

public class Employee {
String name = "John";
int age = 25;
boolean isPermanent = true;
}

当您创建/更新上述模型的记录时,DynamoDB 将生成一个事件,其中包含旧记录(图像)和新记录(这当然取决于您的配置)。

现在回到类型检查:
name字段是String,这导致输入键name和值atrbValue.s = "John"
age字段int,这导致输入键age和值atrbValue.n = "25"
isPermanent字段boolean,这导致输入键isPermanent和值atrbValue.bOOL = true

因此,您可以看到没有快捷方式 如何将Map<String, AttributeValue>转换为Map<String, Object>.


但你可以这样做:

Map<String, Object> result = new HashMap<String, Object>(); 
AttributeValue defaultValue = new AttributeValue();
result.put("name", image.getOrDefault("name", defaultValue).getS());
result.put("age", Integer.valueOf(image.getOrDefault("age", defaultValue).getN()));
result.put("isPermanent", image.getOrDefault("isPermanent", defaultValue).getBOOL());

有关AttributeValue的更多信息,请查看 AWS 文档。

这可以通过内置的类 ItemUtils 轻松实现。检查 toSimpleMapValue 的实现。该实现本质上是递归的,它遍历 Map<String、AttributeValue>并将其转换为简单的映射对象。我只是复制了转换所必需的方法。

如果类型兼容,则可以使用正确的泛型类型创建映射的副本:

final Map<String, AttributeValue> tmp = record.getDynamodb.getNewImage();   
final Map<String, Object> map = new HashMap<>(tmp)

最新更新