【问题标题】:AWS DynamoDB multiple "NE" string filters?AWS DynamoDB 多个“NE”字符串过滤器?
【发布时间】:2015-03-16 00:25:19
【问题描述】:

我正在尝试扫描/查询 AWS DynamoDB 表中的项目列表,其中 id(单个字符串)不等于字符串 A、B、C、D 等中的任何一个。

我尝试过这样的事情:

for (String itemString : items) {
  scanExpression.addFilterCondition("id", 
      new Condition().withComparisonOperator(ComparisonOperator.NE)
      .withAttributeValueList(new AttributeValue().withS(itemString)));
}

PaginatedScanList<Items> result = mapper.scan(Item.class, scanExpression);

似乎发生的情况是,每次我添加过滤器时,它都会覆盖以前的值,因此扫描只检查一个 itemString,而不是几个。是我遗漏了什么,还是这是 DynamoDB 的限制?

注意:如果重要的话,在我的示例中,我列出了四个值(A、B、C、D),但在生产中,这可能是数百个值的列表。

【问题讨论】:

    标签: java android search amazon-dynamodb


    【解决方案1】:

    你说你这样做的方式“覆盖以前的值”是正确的。这是DynamoDBScanExpression上1.9.23 SDK的相关代码:

    public void addFilterCondition(String attributeName, Condition condition) {
        if ( scanFilter == null )
            scanFilter = new HashMap<String, Condition>();
    
        scanFilter.put(attributeName, condition);
    }
    

    由于您的attributeName 对于puts 都将是id,因此在这种情况下,最后一个值将获胜。

    在我看来,这是 DynamoDBScanExpression 的不良行为,我什至更倾向于说这是一个应该报告的错误。文档没有说明何时添加了重复的 attributeName 并且方法名称使它看起来像是意外行为。

    除了构建整个过滤器表达式之外,我没有找到解决此问题的好方法。

    另一个注意事项:在documentation 上,我没有看到过滤器表达式的长度限制以及请求中允许的ExpressionAttributeNamesExpressionAttributeValues 的数量。如果您尝试过滤掉大量属性值,可能会考虑到这一点,但我还没有找到任何关于该限制可能是什么或您应该期待什么行为的文档。

    StringJoiner filterExpression = new StringJoiner(" AND ");
    Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
    int itemAttributeSuffix = 0;
    for (String itemString : items) {
        StringBuilder expression = new StringBuilder("#idname")
                .append(" ")
                .append("<>")
                .append(" ")
                .append(":idval")
                .append(itemAttributeSuffix);
        filterExpression.add(expression);
        expressionAttributeValues.put(":idval" + itemAttributeSuffix++,
            new AttributeValue().withS(itemString));
    }
    Map<String, String> expressionAttributeNames = Collections.singletonMap("#idname", "id");
    scanExpression.setFilterExpression(filterExpression.toString());
    scanExpression.setExpressionAttributeNames(expressionAttributeNames);
    scanExpression.setExpressionAttributeValues(expressionAttributeValues);
    
    PaginatedScanList<Items> result = mapper.scan(Item.class, scanExpression);
    

    【讨论】:

    • 这种方法效果很好,至少在小规模测试中是这样,但看看它如何在更大范围内工作会很有趣。感谢您的周到回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多