首页 文章

DynamoDB获取范围键或全局辅助列的单列列表

提问于
浏览
0

我有一个包含视频信息的DynamoDB表 .

目前“videoID”是主(哈希)键,“类别”是范围(排序)键 .

我想获得所有“类别”(范围键)的列表,以便我可以允许用户从一个可用的视频类别中进行选择 .

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,我可以通过哪种方式查找项目吗?

要么

是扫描整个 table 的唯一方法吗?

在此先感谢您的帮助

2 回答

  • 0
    Is the only way of doing it scanning the whole table?
    

    -NO,你可以实现GSI来避免它

    Is there a way to do to find the items in Category by querying just the range key?
    
    • 是的,如果你不想扫描整个表,那么你需要创建GSI,它将Category作为Hash . 此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

  • 0

    以下是使用GSI创建 Videos 表的示例代码 .

    Create "Videos" table with 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;
    
        }
    

    Query GSI by category:-

    这里输入只是类别,它是使用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;
    
        }
    

相关问题