扫描操作时Dynamo db中的分页

Pal*_*hik 0 database pagination json amazon-web-services amazon-dynamodb

我想扫描我的 Dynamo db 表并对其应用分页。在我的请求中,我想从我想要开始分页的地方发送号码。说,例如,我发送的请求的 start = 3 和 limit = 10,其中 start 是我希望扫描从表中的第三个项目开始,而限制最多为 10 个项目。但是我可以使用 .withLimit() 方法来实现限制(我使用的是 java)。我遵循了这个aws 文档。以下是我想要实现的代码:

<Map<String, AttributeValue>> mapList = new ArrayList<>();
      AmazonDynamoDB client =AmazonDynamoDBClientBuilder.standard().build();

      Gson gson = new GsonBuilder().serializeNulls().create();

      Map<String, AttributeValue> expressionAttributeValues = new 
      HashMap<String,AttributeValue>(); 
      expressionAttributeValues.put(":name",
      newAttributeValue().withS(name));

      List<ResponseDomain> domainList = new ArrayList<>(); 
      ResponseDomain responseDomain = null;

      //lastKeyEvaluated = start
      Map<String, AttributeValue> lastKeyEvaluated = null; 
      do { 
      ScanRequest scanRequest = new 
      ScanRequest().withTableName(STUDENT_TABLE)
      .withProjectionExpression("studentId, studentName")
      .withFilterExpression("begins_with(studentName, :name)")
      .withExpressionAttributeValues(expressionAttributeValues).
      withExclusiveStartKey(lastKeyEvaluated);

      ScanResult result = client.scan(scanRequest);

      for (Map<String, AttributeValue> item : result.getItems()) { 
      responseDomain = gson.fromJson(gson.toJson(item), 
      ResponseDomain.class); 
      domainList.add(responseDomain);


      } lastKeyEvaluated = result.getLastEvaluatedKey(); 
      } while (lastKeyEvaluated!= null); 
      //lastKeyEvaluated = size

      return responseDomain;
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我被困在 3 个地方:

  1. 如何将 lastKeyEvaluated 设置为我的起始值,即 3
  2. 在 while 条件下,我如何指定我的限制,即 10
  3. 当我尝试将项目从 Json 映射到我的域类时,我遇到了错误。

我是否误解了 dynamodb 中的分页概念或在代码中做错了什么。由于我是新手,任何指导都将受到高度赞赏。

小智 5

  1. 您只能通过ExclusiveStartKey从某个地方开始阅读。这个键是你的表的主键。如果你知道你的项目键,你可以像这样使用它(例如你的表主键是studentId):

    Map<String, AttributeValue> lastKeyEvaluated = new HashMap<String,AttributeValue>();
    lastKeyEvaluated.put("studentId", new AttributeValue(STUDENTID));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 当您在 dynamo 中指定limit = N 时,您正在设置它应该只从表中读取N 个项目。在读取N 个项目后应用任何过滤。请参阅限制结果集中的项目数。这可能会给您带来比预期更少的结果。因此,您可以在代码中创建一个变量来发送请求,直到达到预期的限制并切断额外的结果。

    int N = 10;
    List<Map<String, AttributeValue>> itemsList = new ArrayList<>();
    do {
       // scanRequest.withLimit(N)
    
       ...
    
       itemList.addAll(result.getItems());
    
       if(itemsList.size() >= N) {
           itemsList = itemsList.subList(0, N);
           break;
       }
    } while (lastKeyEvaluated != null && itemsList.size() < N);
    
    // process the itemsList
    
    Run Code Online (Sandbox Code Playgroud)
  3. Dynamo 使用它自己的 json 结构。请参阅Dynamo 响应语法。您可以按照在 dynamo 中存储属性的方式获取属性的值。如果studentId是一个字符串,那么它可能是这样的:

    for (Map<String, AttributeValue> item : result.getItems()) {
        responseDomain = new ResponseDomain();
        responseDomain.setId(item.get("studentId").getS());
        domainList.add(responseDomain);
    }
    
    Run Code Online (Sandbox Code Playgroud)