DynamoDB: Как считывать фактическое значение поля из значения атрибута?

#java #amazon-web-services #aws-lambda #amazon-dynamodb #amazon-dynamodb-streams

Вопрос:

Я использую AWS Lambda, написанную на java, для обработки потоков 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
        }
    }
}
 

Мне нужно обработать запись дальше.

Для этого его нужно преобразовать в a Map<String, Object> .
Полученные данные будут иметь формат: { "id":{"s":"777"}} .
Но я хочу преобразовать их в {"id":"777"} , чтобы я мог легко анализировать объект карты. Но есть также вложенные массивы и карты. Также запись очень сложная, состоящая из вложенных массивов и карт. Как этого добиться?

Комментарии:

1. Как его следует преобразовать? An AttributeValue уже является Object ( AttributeValue extends Object ). Вам нужен актерский состав или фактическое преобразование?

2. Мне нужно преобразовать его в объекты карты. в основном используется карта пар ключевых значений, где значение может быть списком, картой, строкой или int и т. Д.

3. Зачем именно вам нужна карта типа Map<String, Object> ?

Ответ №1:

Я понимаю , что вы хотите преобразовать 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.

Комментарии:

1. Оказывается, класс com.amazonaws.services.dynamodbv2.документ. Предметы-это именно то, что мне было нужно.

Ответ №2:

Если типы совместимы, вы можете создать копию карты с правильными универсальными типами:

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

Комментарии:

1. Полученные данные будут иметь формат: { «id»:{«s»:»777″}}. Я хочу преобразовать их в {«id»:»777″}, чтобы я мог легко анализировать объект карты. Но есть также вложенные массивы и карты.

2. @mightyMouse ооочень… в чем ваш настоящий вопрос? 🙂

Ответ №3:

Этого можно легко достичь с помощью встроенных элементов класса. Проверьте реализацию toSimpleMapValue. Реализация рекурсивна по своей природе, и она проходит по схеме Map<Строка, значение атрибута> и преобразует ее в простой объект карты. Я просто скопировал необходимые методы, необходимые для преобразования.