DynamoDB: Bagaimana cara membaca nilai bidang aktual dari AttributeValue?

Saya menggunakan AWS Lambda yang ditulis dalam java untuk memproses Aliran DynamoDB. Ini kodenya:

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
        }
    }
}

Saya perlu memproses catatan itu lebih lanjut.

Untuk itu perlu diubah menjadi Map<String, Object>.
Data yang diterima akan berformat: { "id":{"s":"777"}}.
Namun saya ingin mengubahnya menjadi {"id":"777"}, agar saya dapat mengurai objek peta dengan mudah . Tapi ada juga array dan peta bersarang. Catatannya juga sangat rumit yang terdiri dari array dan peta bersarang. Bagaimana cara mencapainya?


person mightyMouse    schedule 16.03.2021    source sumber
comment
Bagaimana cara mengonversinya? Sebuah AttributeValue sudah menjadi Object (AttributeValue extends Object). Apakah Anda memerlukan pemeran atau konversi yang sebenarnya?   -  person knittl    schedule 16.03.2021
comment
Saya perlu melemparkannya ke objek peta. pada dasarnya dimasukkan ke dalam peta pasangan nilai kunci di mana nilai dapat berupa daftar atau peta atau string atau int, dll.   -  person mightyMouse    schedule 16.03.2021
comment
Mengapa sebenarnya Anda memerlukan peta tipe Map<String, Object>?   -  person knittl    schedule 16.03.2021


Jawaban (3)


Saya memahami Anda ingin mengonversi Map<String, AttributeValue> menjadi Map<String, Object>, jadi jawaban @knittl benar jika Anda menginginkan Objek tetapi Anda ingin mendapatkan nilai literal dari setiap bidang alih-alih hanya memasukkan AttributeValue ke Object, jika saya memahami Anda dengan benar.

Jadi jika Anda memeriksa kode untuk 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;
  ...

Anda dapat melihat ada banyak kolom tipe yang terdaftar dan digunakan untuk memaksakan pengetikan. Kami akan kembali ke sini.
Karena Anda mendapatkan ini sebagai Acara Aliran DynamoDB, kami memerlukan kelas model yang dapat kami bicarakan :)

Katakanlah kita memiliki kelas model sederhana ini:

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

Saat Anda membuat/memperbarui catatan model di atas, DynamoDB akan menghasilkan peristiwa yang berisi catatan lama (gambar) dan yang baru (tentu saja ini tergantung pada konfigurasi Anda).

Sekarang kembali ke pemeriksaan tipe:
name field adalah String, ini menghasilkan entri kunci name dan nilai atrbValue.s = "John"
age bidang adalah int, ini menghasilkan entri kunci age dan nilai atrbValue.n = "25"
Bidang isPermanent adalah boolean, ini menghasilkan masuknya kunci isPermanent dan nilai atrbValue.bOOL = true

Jadi Anda dapat melihat tidak ada jalan pintas untuk mengubah Map<String, AttributeValue> menjadi Map<String, Object>.


Tetapi Anda dapat melakukan ini:

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());

Lebih lanjut tentang AttributeValue, lihat dokumentasi AWS.

person dsharew    schedule 24.03.2021
comment
Ternyata kelas com.amazonaws.services.dynamodbv2.document.ItemUtils persis seperti yang saya butuhkan. - person mightyMouse; 25.03.2021

Jika tipenya kompatibel, Anda dapat membuat salinan peta dengan tipe generik yang benar:

final Map<String, AttributeValue> tmp = record.getDynamodb.getNewImage();   
final Map<String, Object> map = new HashMap<>(tmp)
person knittl    schedule 16.03.2021
comment
Data yang diterima akan berformat: { id:{s:777}}. saya ingin mengubahnya menjadi {id:777} sehingga saya dapat mengurai objek peta dengan mudah. Tapi ada juga array dan peta bersarang. - person mightyMouse; 16.03.2021
comment
@mightyMouse sooo… apa pertanyaan Anda sebenarnya? :) - person knittl; 16.03.2021

Hal ini dapat dicapai dengan mudah dengan kelas bawaan ItemUtil. Periksa implementasi toSimpleMapValue. Implementasinya bersifat rekursif dan melintasi skema Map‹String, AttributeValue› dan mengubahnya menjadi objek peta sederhana. Saya hanya menyalin metode yang diperlukan untuk transformasi.

person mightyMouse    schedule 24.03.2021