rpm*_*rtz 7 java amazon-web-services amazon-dynamodb
通过全局二级索引查询DynamoDB表时是否可以指定独占启动键?
我正在使用aws-java-sdk版本1.6.10并使用a QueryExpression和a 执行查询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);
Run Code Online (Sandbox Code Playgroud)
这会导致400错误,指出指定的开始键无效.TIMESTAMP是表索引和全局二级索引的范围键,属性值对是有效的(即表中有一个项目,其值作为索引的哈希和范围键传递,属性传递为索引是全局二级索引的哈希键).
有什么我错过了或这是不可能的?
小智 7
有同样的问题,只是排序.:)太迟回答这个问题,但希望有人会发现有用.
使用辅助索引和分页查询或扫描表时,应该包括表的主键和索引(作为键),以及设置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"));
Run Code Online (Sandbox Code Playgroud)
根据亚马逊流域,这是不可能的: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;
Run Code Online (Sandbox Code Playgroud)
请注意,该marshallIntoObject方法不赞成使用类中的受保护方法DynamoDBMapper,但是编写marshaller很容易进行未来的升级以打破映射.
不像使用映射器那样优雅,但它完成了同样的事情.
好吧,我参加聚会超级迟到了,但我已经弄清楚发生了什么。这不是错误,它可以正常工作,但我从未在文档中看到过它。
事实证明,在全局二级索引中,一级索引被用作“决胜局”。也就是说,如果两个对象具有相同的 GSI 哈希+排序键,则使用主索引在 GSI 中对它们进行排序。这意味着当您使用独占启动键查询 GSI 时,您需要 GSI 索引和主索引才能从正确的位置开始。
也许这会帮助某人。我知道它难倒了我一段时间!
| 归档时间: |
|
| 查看次数: |
9982 次 |
| 最近记录: |