首页 文章

具有独占启动密钥的DynamoDB全局二级索引

提问于
浏览
6

通过全局二级索引查询DynamoDB表时是否可以指定独占启动键?

我正在使用aws-java-sdk版本1.6.10并使用 QueryExpressionDynamoDBMapper 执行查询 . 这里's the gist of what I' m试图这样做:

MappedItem key = new MappedItem();
item.setIndexedAttribute(attributeValue);

Map<String, AttributeValue> exclusiveStartKey = new HashMap<String, AttributeValue>();
exclusiveStartKey.put(MappedItem.INDEXED_ATTRIBUTE_NAME, new AttributeValue().withS(attributeValue));
exclusiveStartKey.put(MappedItem.TIMESTAMP, new AttributeValue().withN(startTimestamp.toString()));

DynamoDBQueryExpression<MappedItem> queryExpression = new DynamoDBQueryExpression<MappedItem>();
queryExpression.withIndexName(MappedItem.INDEX_NAME);
queryExpression.withConsistentRead(Boolean.FALSE);
queryExpression.withHashKeyValues(key);
queryExpression.setLimit(maxResults * 2);
queryExpression.setExclusiveStartKey(exclusiveStartKey);

这会导致400错误,指出指定的开始键无效 . TIMESTAMP是表索引和全局二级索引的范围键,属性值对是有效的(即表中有一个项目,其值作为索引的哈希和范围键传递,属性传递为索引是全局二级索引的哈希键) .

有什么我错过了或这是不可能的?

2 回答

  • 6

    根据亚马逊流域,这是不可能的:https://forums.aws.amazon.com/thread.jspa?threadID=146102&tstart=0

    但是,对我的用例有用的解决方法是,只需指定 RangeKeyCondition 大于最后检索到的对象's timestamp. Here'的想法:

    Condition hashKeyCondition = new Condition();
    hashKeyCondition.withComparisonOperator(ComparisonOperator.EQ).withAttributeValueList(new AttributeValue().withS(hashKeyAttributeValue));
    
    Condition rangeKeyCondition = new Condition();
    rangeKeyCondition.withComparisonOperator(ComparisonOperator.GT).withAttributeValueList(new AttributeValue().withN(timestamp.toString()));
    
    Map<String, Condition> keyConditions = new HashMap<String, Condition>();
    keyConditions.put(MappedItem.INDEXED_ATTRIBUTE_NAME, hashKeyCondition);
    keyConditions.put(MappedItem.TIMESTAMP, rangeKeyCondition);
    
    
    QueryRequest queryRequest = new QueryRequest();
    queryRequest.withTableName(tableName);
    queryRequest.withIndexName(MappedItem.INDEX_NAME);
    queryRequest.withKeyConditions(keyConditions);
    
    QueryResult result = amazonDynamoDBClient.query(queryRequest);
    
    List<MappedItem> mappedItems = new ArrayList<MappedItem>();
    
    for(Map<String, AttributeValue> item : result.getItems()) {
        MappedItem mappedItem = dynamoDBMapper.marshallIntoObject(MappedItem.class, item);
        mappedItems.add(mappedItem);
    }
    
    return mappedItems;
    

    请注意,不推荐使用 marshallIntoObject 方法,而是支持 DynamoDBMapper 类中的受保护方法,但是编写marshaller很容易进行未来的升级以打破映射 .

    不像使用映射器那样优雅,但它完成了同样的事情 .

  • 6

    有同样的问题,只是排序 . :)太迟回答这个问题,但希望有人会发现有用 .

    当您使用二级索引和分页查询或扫描表时,应该包括 tableindex (作为键)的主键,以及设置 ExclusiveStartKey 时的最后评估值(作为属性值) .

    只需从查询或扫描结果中查看 LastEvaluatedKey 即可查看格式 .

    // let's just assume that we have a table to store details of products
    Map<String, AttributeValue> exclusiveStartKey = new HashMap<String, AttributeValue>();
    // primary key of the table
    exclusiveStartKey.put("productId", new AttributeValue().withS("xxxx"));
    exclusiveStartKey.put("produtSize", new AttributeValue().withS("XL"));
    // primary key of the index
    exclusiveStartKey.put("categoryId", new AttributeValue().withS("xx01"));
    exclusiveStartKey.put("subCategoryId", new AttributeValue().withN("1"));
    

相关问题