DynamoDB: จะอ่านค่าฟิลด์จริงจาก AttributeValue ได้อย่างไร

ฉันใช้ 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
        }
    }
}

ฉันจำเป็นต้องประมวลผลบันทึกเพิ่มเติม

เพื่อที่จะต้องแปลงเป็น Map<String, Object>.
ข้อมูลที่ได้รับจะอยู่ในรูปแบบ: { "id":{"s":"777"}}.
แต่ฉันต้องการแปลงเป็น {"id":"777"} เพื่อให้ฉันสามารถแยกวิเคราะห์วัตถุแผนที่ได้อย่างง่ายดาย . แต่ก็มีอาร์เรย์และแผนที่ที่ซ้อนกันเช่นกัน นอกจากนี้บันทึกยังมีความซับซ้อนมากซึ่งประกอบด้วยอาร์เรย์และแผนที่ที่ซ้อนกัน จะบรรลุเป้าหมายนี้ได้อย่างไร?


comment
ควรแปลงอย่างไร AttributeValue ก็คือ Object (AttributeValue extends Object) อยู่แล้ว คุณต้องการนักแสดงหรือการแปลงจริงหรือไม่?   -  person knittl    schedule 16.03.2021
comment
ฉันต้องโยนมันลงในวัตถุแผนที่ โดยพื้นฐานแล้วโยนลงในแผนที่ของคู่ค่าคีย์โดยที่ค่าสามารถเป็นรายการหรือแผนที่หรือสตริงหรือ int เป็นต้น   -  person mightyMouse    schedule 16.03.2021
comment
เหตุใดคุณจึงต้องมีแผนที่ประเภท Map<String, Object>   -  person knittl    schedule 16.03.2021


คำตอบ (3)


ฉันเข้าใจว่าคุณต้องการแปลง Map<String, AttributeValue> เป็น Map<String, Object> ดังนั้นสิ่งที่ @knittl ตอบนั้นถูกต้องถ้าคุณต้องการ Object แต่คุณต้องการได้รับค่าตามตัวอักษรของแต่ละฟิลด์แทนที่จะเพียงแค่ส่ง 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

person dsharew    schedule 24.03.2021
comment
ปรากฎว่าคลาส com.amazonaws.services.dynamodbv2.document.ItemUtils เป็นสิ่งที่ฉันต้องการ - person mightyMouse; 25.03.2021

หากประเภทต่างๆ เข้ากันได้ คุณสามารถสร้างสำเนาของแผนที่ด้วยประเภททั่วไปที่ถูกต้องได้:

final Map<String, AttributeValue> tmp = record.getDynamodb.getNewImage();   
final Map<String, Object> map = new HashMap<>(tmp)
person knittl    schedule 16.03.2021
comment
ข้อมูลที่ได้รับจะมีรูปแบบ: { id:{s:777}} ฉันต้องการแปลงเป็น {id:777} เพื่อให้สามารถแยกวิเคราะห์วัตถุแผนที่ได้อย่างง่ายดาย แต่ก็มีอาร์เรย์และแผนที่ที่ซ้อนกันเช่นกัน - person mightyMouse; 16.03.2021
comment
@mightyMouse ดังนั้น… คำถามที่แท้จริงของคุณคืออะไร? :) - person knittl; 16.03.2021

ซึ่งสามารถทำได้ง่ายๆ ด้วยคลาสในตัว ItemUtils ตรวจสอบการใช้งาน toSimpleMapValue การใช้งานเป็นแบบเรียกซ้ำโดยธรรมชาติ และจะข้ามสคีมาของ Map‹String, AttributeValue› และแปลงเป็นออบเจ็กต์แผนที่แบบธรรมดา ฉันเพียงแค่คัดลอกวิธีการที่จำเป็นสำหรับการแปลง

person mightyMouse    schedule 24.03.2021