简体   繁体   English

DynamoDb 扫描过滤器不返回某些请求的结果

[英]DynamoDb scan filter not returning results for some requests

I have a table with two columns FirstId and SecondId.我有一个包含两列 FirstId 和 SecondId 的表。 FirstId is the primary key and SecondId is not indexed . FirstId 是主键,而 SecondId 未编入索引

FirstId |  SecondId    
--------------------
  abc   |  123     
  xyz   |  789     

I'm doing a scan filter to get the FirstId value from the SecondId using the JavaSDK.我正在执行扫描过滤器以使用 JavaSDK 从 SecondId 获取 FirstId 值。 I've around 12k entries and it was working fine.我有大约 12k 个条目,并且运行良好。 Recently, the scan request has started returning null for some cases, although, I can find the entry in the AWS UI .最近,扫描请求在某些情况下开始返回null ,但我可以在 AWS UI 中找到该条目

Here is my code这是我的代码

    Condition scanFilterCondition = new Condition()
        .withComparisonOperator(ComparisonOperator.EQ)
        .withAttributeValueList(new AttributeValue().withS(secondIdValue));
    
    Map<String, Condition> conditions = new HashMap<String, Condition>();
    conditions.put("SecondId", scanFilterCondition);

    ScanRequest scanRequest = new ScanRequest()
            .withTableName(table)
            .withScanFilter(conditions);
    
    ScanResult result = mDBClient.scan(scanRequest);
    if(result.getItems().size() == 0) {
        return null;
    }
        
    Map<String, AttributeValue> item = result.getItems().get(0);
    
    return item.get("FirstId").getS();

I'm assuming this might be due to the operation getting expensive as the data grows!我假设这可能是因为随着数据的增长,操作变得越来越昂贵! Is there a way I can optimize this request?有没有办法优化这个请求? Or, is there something that I'm missing?或者,有什么我想念的吗?

Your problem might be explained by understanding how DynamoDB handles scans, filters and pagination.您的问题可能通过了解 DynamoDB 如何处理扫描、过滤器和分页来解释。

A few things to remember:要记住的几件事:

  • Each scan can only read up to 1MB of data at a time每次scan最多只能读取 1MB 的数据
  • Filter operations are applied after the scan (or query ) scan (或query应用过滤操作
  • Scan will search the entire database扫描将搜索整个数据库

Taking these into consideration, it's possible you will have to paginate through several empty scan results before finding (or not finding) the data you are after.考虑到这些因素,在找到(或未找到)您要查找的数据之前,您可能需要对几个空的扫描结果进行分页。 You could be reading a full 1MB of data, filtering it all out, and returning an empty result set to the client.您可能正在读取完整的 1MB 数据,将其全部过滤掉,然后向客户端返回一个空结果集。 result.getItems().size() may be zero, but that doesn't mean that you don't have to perform another scan operation to complete the search. result.getItems().size()可能为零,但这并不意味着您不必执行另一个scan操作来完成搜索。

I'm not certain that this is your problem, but it's easy to verify.我不确定这是您的问题,但很容易验证。 DDB will return a field LastEvaluatedKey with your scan results if the scan operation is being paginated.如果scan操作正在分页,DDB 将返回一个包含scan结果的字段LastEvaluatedKey If so, you'll need to make another scan request to continue the scan operation.如果是这样,您将需要发出另一个scan请求以继续scan操作。

Again, this may not be your problem, but it could explain why you aren't seeing the results you expect from a single scan operation.同样,这可能不是您的问题,但它可以解释为什么您没有看到从单次scan操作中获得的结果。

I had a long debugging session with the AWS support engineers and still, we could not figure out the reason.我与 AWS 支持工程师进行了长时间的调试会话,但我们仍然无法找出原因。 AWS CLI and UI both were returning the result, but not the JAVA SDK scan query. AWS CLI 和 UI 都返回了结果,但没有返回 JAVA SDK 扫描查询。

So, I created a GSI for SecondId and changed my code to do index-query rather than a scan query, and it fixed the problem for me.因此,我为SecondId创建了一个 GSI 并更改了我的代码以执行索引查询而不是扫描查询,它为我解决了问题。

    Table table = dynamoDB.getTable(table);
    Index index = table.getIndex("SecondId-index");

    QuerySpec spec = new QuerySpec()
            .withKeyConditionExpression("SecondId = :second_id")
            .withValueMap( new ValueMap()
                .withString(":second_id", secondIdValue));

    ItemCollection<QueryOutcome> items = index.query(spec);

    if(!items.iterator().hasNext()) {
        return null;
    }
    
    JsonNode result = jsonMapper.readTree(items.iterator().next().toJSON());

    return result.get("FirstId").asText();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM