如何访问 Dynamodb 的原始 JSON 元素?

How to access Dynamodb's original JSON elements?

我正在尝试使用测试中配置的以下 dynamodb 事件输入手动测试我的 lambda -

我们称之为Json-1

 {
  "Records": [
    {
      "eventID": "1",
      "eventVersion": "1.0",
      "dynamodb": {
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "NewImage": {
          "Message": {
            "S": "New item!"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES",
        "SequenceNumber": "111",
        "SizeBytes": 26
      },
      "awsRegion": "us-west-2",
      "eventName": "INSERT",
      "eventSourceARN": eventsourcearn,
      "eventSource": "aws:dynamodb"
    },
    {
      "eventID": "2",
      "eventVersion": "1.0",
      "dynamodb": {
        "OldImage": {
          "Message": {
            "S": "New item!"
          },
          "Id": {
            "N": "101"
          }
        },
        "SequenceNumber": "222",
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "SizeBytes": 59,
        "NewImage": {
          "Message": {
            "S": "This item has changed"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES"
      },
      "awsRegion": "us-west-2",
      "eventName": "MODIFY",
      "eventSourceARN": sourcearn,
      "eventSource": "aws:dynamodb"
    },
    {
      "eventID": "3",
      "eventVersion": "1.0",
      "dynamodb": {
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "SizeBytes": 38,
        "SequenceNumber": "333",
        "OldImage": {
          "Message": {
            "S": "This item has changed"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES"
      },
      "awsRegion": "us-west-2",
      "eventName": "REMOVE",
      "eventSourceARN": sourcearn,
      "eventSource": "aws:dynamodb"
    }
  ]
}

然而,json 的 dynamodb 项目看起来像这样 -

我们称这个为Json-2

{
  "id": {
    "S": "RIGHT-aa465568-f4c8-4822-9c38-7563ae0cd37b-1131286033464633.jpg"
  },
  "lines": {
    "L": [
      {
        "M": {
          "points": {
            "L": [
              {
                "L": [
                  {
                    "N": "0"
                  },
                  {
                    "N": "874.5625"
                  }
                ]
              },
              {
                "L": [
                  {
                    "N": "1765.320601851852"
                  },
                  {
                    "N": "809.7800925925926"
                  }
                ]
              },
              {
                "L": [
                  {
                    "N": "3264"
                  },
                  {
                    "N": "740.3703703703704"
                  }
                ]
              }
            ]
          },
          "type": {
            "S": "guard"
          }
        }
      }
    ]
  },
  "modified": {
    "N": "1483483932472"
  },
  "qastatus": {
    "S": "reviewed"
  }
}

使用下面的 lambda 函数,我可以连接到我的 table。我的目标是创建一个弹性搜索将接受的 json。

@Override
    public Object handleRequest(DynamodbEvent dynamodbEvent, Context context) {

        List<DynamodbEvent.DynamodbStreamRecord> dynamodbStreamRecordlist = dynamodbEvent.getRecords();

        DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient());
        log.info("Whole event - "+dynamodbEvent.toString());

        dynamodbStreamRecordlist.stream().forEach(dynamodbStreamRecord -> {
            if(dynamodbStreamRecord.getEventSource().equalsIgnoreCase("aws:dynamodb")){
                log.info("one record - "+dynamodbStreamRecord.getDynamodb().toString());
                log.info(" getting N from new image "+dynamodbStreamRecord.getDynamodb().getNewImage().toString());

                String tableName = getTableNameFromARN(dynamodbStreamRecord.getEventSourceARN());
                log.info("Table name :"+tableName);

                Map<String, AttributeValue> keys = dynamodbStreamRecord.getDynamodb().getKeys();
                log.info(keys.toString());

                AttributeValue attributeValue = keys.get("Id");
                log.info("Value of N: "+attributeValue.getN());

                Table table = dynamoDB.getTable(tableName);


            }
        });

        return dynamodbEvent;
    }

弹性搜索期望的 JSON 项目的格式是这样的,这就是我想要将测试输入 json 映射到 -

我们称这个为Json-3

{
    _index: "bar-guard",
    _type: "bar-guard_type",
    _id: "LEFT-b1939610-442f-4d8d-9991-3ca54685b206-1147042497459511.jpg",
    _score: 1,
    _source: {
        @SequenceNumber: "4901800000000019495704485",
        @timestamp: "2017-01-04T02:24:20.560358",
        lines: [{
            points: [[0,
            1222.7129629629628],
            [2242.8252314814818,
            1254.702546296296],
            [4000.0000000000005,
            1276.028935185185]],
            type: "barr"
        }],
        modified: 1483483934697,
        qastatus: "reviewed",
        id: "LEFT-b1939610-442f-4d8d-9991-3ca54685b206-1147042497459511.jpg"
    }
},

所以我需要的是读取Json-1并将其映射到Json-3。 但是,Json-1 似乎并不完整,即它没有 dynamodb json 具有的信息 - 就像 Json-2.

中的点和线

因此,我尝试与原始 table 建立连接,然后使用 ID 读取线和点的附加信息。

我不确定这是否是正确的方法。基本上,想找出一种方法来获取 dynamodb 具有的实际 JSON 而不是具有属性类型的方法 如何使用 java 从 json-2 获取线和点?我知道我们在 javascript 中有 DocumentClient,但我正在寻找 java 中的内容。

此外,在这里遇到了一个转换器,但对我没有帮助- https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/converter.js

这是我应该使用 DynamoDBMapper 或 ScanJavaDocumentAPI 的东西吗?

http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html#marshallIntoObjects-java.lang.Class-java.util.List-com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig-

如果是,我有点不知道如何在下面的代码中做到这一点 -

ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
                ScanResult result = dynamoDBClient.scan(scanRequest);
                for(Map<String, AttributeValue> item : result.getItems()){
                    AttributeValue value = item.get("lines");
                    if(value != null){
                        List<AttributeValue> values = value.getL();
                        for(AttributeValue value2 : values){
                            //what next?
                        }
                    }
                }

好的,这似乎对我有用。

ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
                ScanResult result = dynamoDBClient.scan(scanRequest);

                for(Map<String, AttributeValue> item : result.getItems()){
                    AttributeValue value = item.get("lines");
                    if(value != null){
                        List<AttributeValue> values = value.getL();

                        for(AttributeValue value2 : values){

                                if(value2.getM() != null)
                            {
                                Map<String, AttributeValue> map = value2.getM();
                                        AttributeValue points = map.get("points");
                                    List<AttributeValue> pointsvalues = points.getL();
                                    if(!pointsvalues.isEmpty()){
                                        for(AttributeValue valueOfPoint : pointsvalues){
                                            List<AttributeValue> pointList = valueOfPoint.getL();
                                            for(AttributeValue valueOfPoint2 : pointList){

                                            }
                                        }
                                    }
                            }
                        }
                    }
                }