DynamoDB получить список одного столбца ключей диапазона или глобального вторичного

У меня есть таблица DynamoDB, которая содержит информацию о видео.

В настоящее время»videoID «является основным (хэш) ключом, а» Category » — ключом диапазона (сортировки).

Я хочу получить список всех «категорий» (ключей диапазона), чтобы позволить пользователю выбрать одну из доступных категорий видео.

https://www.quora.com/What-are-some-good-ways-to-extract-one-single-column-from-a-DynamoDB-table

Я читал, что если вы изменили, измените атрибут «категория» на глобальный вторичный индекс, вы можете вернуть элементы для этого GSI. Но я не смог найти, как это сделать.

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSIJavaDocumentAPI.html

Таким образом, я думаю, что это дает мне три вопроса:

Есть ли способ найти элементы в категории, запросив только ключ диапазона?

Если изменить категорию на GSI, можно ли найти элементы таким образом?

или

Является ли это единственным способом сканирования всей таблицы?

Заранее спасибо за помощь

2 ответа

  1. Is the only way of doing it scanning the whole table?
    

    — Нет, вы можете реализовать GSI, чтобы избежать этого

    Is there a way to do to find the items in Category by querying just the range key?
    

    — Да, если вы не хотите сканировать всю таблицу, то вам нужно создать GSI, который будет иметь категорию как хэш. Этот GSI будет действовать как таблица сама по себе, и вы можете запросить на нем, передавая значения категории.

    If change Category to a GSI can I find the items that way?
    

    — Да, вы можете запросить на GSI со значениями категории

    I was reading that if you modified change the attribute "Category" to a global secondary index you can return the items for that GSI. But I have not been able to find how to do that.
    

    -Вам нужно создать GSI при создании таблицы, пример приведен в ссылке, которую вы указали, как только это будет сделано, вы можете запросить, что GSI

    Ссылки: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html

  2. Вот пример кода для создания Videosтаблицы с GSI.

    Создать таблицу «видео» с помощью GSI:-

    @Autowired
        private AmazonDynamoDBClient dynamoDBClient;
    
        public Boolean createTableWithGlobalSecondaryIndex(String tableName) {
    
            CreateTableRequest createTableRequest = null;
    
            DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);
    
            try {
    
                ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
                attributeDefinitions.add(new AttributeDefinition().withAttributeName("videoid").withAttributeType("S"));
                attributeDefinitions.add(new AttributeDefinition().withAttributeName("category").withAttributeType("S"));
    
                ArrayList<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>();
                keySchema.add(new KeySchemaElement().withAttributeName("videoid").withKeyType(KeyType.HASH));
                keySchema.add(new KeySchemaElement().withAttributeName("category").withKeyType(KeyType.RANGE));
    
                // Initial provisioned throughput settings for the indexes
                ProvisionedThroughput ptIndex = new ProvisionedThroughput().withReadCapacityUnits(150L)
                        .withWriteCapacityUnits(150L);
    
                GlobalSecondaryIndex videoCategoryGsi = new GlobalSecondaryIndex().withIndexName("VideoCategoryGsi")
                        .withProvisionedThroughput(ptIndex)
                        .withKeySchema(new KeySchemaElement().withAttributeName("category").withKeyType(KeyType.HASH),
                                new KeySchemaElement().withAttributeName("videoid").withKeyType(KeyType.RANGE))
                        .withProjection(new Projection().withProjectionType(ProjectionType.ALL));
    
                createTableRequest = new CreateTableRequest().withTableName(tableName).withKeySchema(keySchema)
                        .withAttributeDefinitions(attributeDefinitions)
                        .withProvisionedThroughput(
                                new ProvisionedThroughput().withReadCapacityUnits(100L).withWriteCapacityUnits(100L))
                        .withGlobalSecondaryIndexes(videoCategoryGsi);
    
                Table table = dynamoDB.createTable(createTableRequest);
    
                table.waitForActive();
    
            } catch (ResourceInUseException re) {
    
                if (re.getErrorMessage().equalsIgnoreCase("Cannot create preexisting table")) {
                    LOGGER.info("Table already exists =============>" + tableName);
                } else if (re.getErrorMessage().contains("Table already exists")) {
                    LOGGER.info("Table already exists =============>" + tableName);
                    LOGGER.info("Message =============>" + re.getErrorCode() + ";" + re.getErrorMessage());
                } else {
    
                    throw new RuntimeException("DynamoDB table cannot be created ...", re);
                }
    
            } catch (Exception db) {
    
                throw new RuntimeException("DynamoDB table cannot be created ...", db);
    
            }
    
            return true;
    
        }
    

    Запрос GSI по категориям:-

    Вот вход просто категория и это запрос с помощью GSI. Другими словами, это не сканирование всей таблицы, а также.

    public List<String> findVideosByCategoryUsingGlobalSecondaryIndex(String category) {
    
            List<String> videoAsJson = new ArrayList<>();
    
            DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);
    
            Table table = dynamoDB.getTable("Videos");
    
            Index index = table.getIndex("VideoCategoryGsi");
    
            ItemCollection<QueryOutcome> items = null;
    
            QuerySpec querySpec = new QuerySpec();
    
            querySpec.withKeyConditionExpression("category = :val1")
                    .withValueMap(new ValueMap()
                            .withString(":val1", category));
            items = index.query(querySpec);
    
            Iterator<Item> pageIterator = items.iterator();
    
    
            while (pageIterator.hasNext()) {
                String videoJson = pageIterator.next().toJSON();
                System.out.println("Video json ==================>" + videoJson);
                videoAsJson.add(videoJson);
            }
    
            return videoAsJson;
    
        }