in services/dynamodb/src/it/java/software/amazon/awssdk/services/dynamodb/SecondaryIndexesIntegrationTest.java [345:488]
public void testQueryWithLocalSecondaryIndex() throws Exception {
String randomHashKeyValue = UUID.randomUUID().toString();
int totalItemsPerHash = 10;
int totalIndexedItemsPerHash = 5;
Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
item.put(HASH_KEY_NAME, AttributeValue.builder().s(randomHashKeyValue).build());
// Items with LSI range key
for (int i = 0; i < totalIndexedItemsPerHash; i++) {
item.put(RANGE_KEY_NAME, AttributeValue.builder().n(Integer.toString(i)).build());
item.put(LSI_RANGE_KEY_NAME, AttributeValue.builder().n(Integer.toString(i)).build());
item.put("attribute_" + i, AttributeValue.builder().s(UUID.randomUUID().toString()).build());
dynamo.putItem(PutItemRequest.builder().tableName(tableName).item(item).build());
item.remove("attribute_" + i);
}
item.remove(LSI_RANGE_KEY_NAME);
// Items without LSI range key
for (int i = totalIndexedItemsPerHash; i < totalItemsPerHash; i++) {
item.put(RANGE_KEY_NAME, AttributeValue.builder().n(Integer.toString(i)).build());
item.put("attribute_" + i, AttributeValue.builder().s(UUID.randomUUID().toString()).build());
dynamo.putItem(PutItemRequest.builder().tableName(tableName).item(item).build());
item.remove("attribute_" + i);
}
/**
* 1) Query-with-LSI (only by hash key)
*/
QueryResponse result = dynamo.query(QueryRequest.builder()
.tableName(tableName)
.indexName(LSI_NAME)
.keyConditions(
Collections.singletonMap(
HASH_KEY_NAME,
Condition.builder().attributeValueList(
AttributeValue.builder()
.s(randomHashKeyValue).build())
.comparisonOperator(
ComparisonOperator.EQ).build())).build());
// Only the indexed items should be returned
assertEquals((Object) totalIndexedItemsPerHash, (Object) result.count());
// By default, the result includes all the projected attributes.
assertEquals(3, result.items().get(0).size());
/**
* 2) Query-with-LSI (by hash + LSI range)
*/
int rangeKeyConditionRange = 2;
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put(
HASH_KEY_NAME,
Condition.builder().attributeValueList(
AttributeValue.builder().s(randomHashKeyValue).build())
.comparisonOperator(ComparisonOperator.EQ).build());
keyConditions.put(
LSI_RANGE_KEY_NAME,
Condition.builder().attributeValueList(AttributeValue.builder()
.n(Integer.toString(rangeKeyConditionRange)).build())
.comparisonOperator(ComparisonOperator.LT).build());
result = dynamo.query(QueryRequest.builder()
.tableName(tableName)
.indexName(LSI_NAME)
.keyConditions(keyConditions).build());
assertEquals((Object) rangeKeyConditionRange, (Object) result.count());
/**
* 3) Query-with-LSI on selected attributes (by Select)
*/
result = dynamo.query(QueryRequest.builder()
.tableName(tableName)
.indexName(LSI_NAME)
.keyConditions(
Collections.singletonMap(
HASH_KEY_NAME,
Condition.builder().attributeValueList(
AttributeValue.builder()
.s(randomHashKeyValue).build())
.comparisonOperator(ComparisonOperator.EQ).build()))
.select(Select.ALL_ATTRIBUTES).build());
// Only the indexed items should be returned
assertEquals((Object) totalIndexedItemsPerHash, (Object) result.count());
// By setting Select.ALL_ATTRIBUTES, all attributes in the item will be returned
assertEquals(4, result.items().get(0).size());
/**
* 4) Query-with-LSI on selected attributes (by AttributesToGet)
*/
result = dynamo.query(QueryRequest.builder()
.tableName(tableName)
.indexName(LSI_NAME)
.keyConditions(
Collections.singletonMap(
HASH_KEY_NAME,
Condition.builder().attributeValueList(
AttributeValue.builder()
.s(randomHashKeyValue).build())
.comparisonOperator(ComparisonOperator.EQ).build()))
.attributesToGet(HASH_KEY_NAME, RANGE_KEY_NAME).build());
// Only the indexed items should be returned
assertEquals((Object) totalIndexedItemsPerHash, (Object) result.count());
// Two attributes as specified in AttributesToGet
assertEquals(2, result.items().get(0).size());
/**
* 5) Exception when using both Selection and AttributeToGet
*/
try {
result = dynamo.query(QueryRequest.builder()
.tableName(tableName)
.indexName(LSI_NAME)
.keyConditions(
Collections.singletonMap(
HASH_KEY_NAME,
Condition.builder().attributeValueList(
AttributeValue.builder()
.s(randomHashKeyValue).build())
.comparisonOperator(ComparisonOperator.EQ).build()))
.attributesToGet(HASH_KEY_NAME, RANGE_KEY_NAME, LSI_RANGE_KEY_NAME)
.select(Select.ALL_PROJECTED_ATTRIBUTES).build());
fail("Should trigger exception when using both Select and AttributeToGet.");
} catch (SdkServiceException exception) {
// Ignored or expected.
}
/**
* 6) Query-with-LSI on selected attributes (by Select.SPECIFIC_ATTRIBUTES)
*/
result = dynamo.query(QueryRequest.builder()
.tableName(tableName)
.indexName(LSI_NAME)
.keyConditions(
Collections.singletonMap(
HASH_KEY_NAME,
Condition.builder().attributeValueList(
AttributeValue.builder()
.s(randomHashKeyValue).build())
.comparisonOperator(
ComparisonOperator.EQ).build()))
.attributesToGet(HASH_KEY_NAME)
.select(Select.SPECIFIC_ATTRIBUTES).build());
// Only the indexed items should be returned
assertEquals((Object) totalIndexedItemsPerHash, (Object) result.count());
// Only one attribute as specified in AttributesToGet
assertEquals(1, result.items().get(0).size());
}