public void testQueryWithLocalSecondaryIndex()

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());
    }