DynamoDB:如何从 AttributeValue 中读取实际字段值?

DynamoDB: How to read actual field value from AttributeValue?

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

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"},这样我就可以很容易地解析地图对象。但是也有嵌套的数组和映射。此外,记录非常复杂,由嵌套数组和映射组成。如何实现?

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

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

我知道您想将 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 流事件,我们需要一个模型 class 我们可以讨论 :)

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

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

当您create/update上述模型的记录时,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 documentation

这可以通过内置 class ItemUtils. Check the implementation of toSimpleMapValue 轻松实现。该实现本质上是递归的,它遍历 Map 的模式并将其转换为简单的地图对象。我只是简单地复制了转换所必需的所需方法。