加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 23:48:48 所属栏目:Java 来源:网络整理
导读:通过全局二级索引查询DynamoDB表时是否可以指定独占启动键? 我正在使用aws-java-sdk版本1.6.10并使用QueryExpression和DynamoDBMapper执行查询.这是我要做的事情的要点: MappedItem key = new MappedItem();item.setIndexedAttribute(attributeValue);MapS
通过全局二级索引查询DynamoDB表时是否可以指定独占启动键?

我正在使用aws-java-sdk版本1.6.10并使用QueryExpression和DynamoDBMapper执行查询.这是我要做的事情的要点:

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是表索引和全局二级索引的范围键,属性值对是有效的(即表中有一个项目,其值作为索引的哈希和范围键传递,属性传递为索引是全局二级索引的哈希键).

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

解决方法

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

但是,对我的用例有用的解决方法是仅指定一个大于上次检索到的对象的时间戳的RangeKeyCondition.这是个主意:

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很容易进行未来的升级以打破映射.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读