Amazon dynamodb 查询某一类别的产品

Amazon dynamodb 查询某一类别的产品,amazon-dynamodb,Amazon Dynamodb,我在DynamoDb中有一个简单的“产品””表。每个产品都有一个categories属性,该属性是一组类别ID,如下所示: [{ "N" : "4" },{ "N" : "5" },{ "N" : "6" },{ "N" : "8" }] 产品表具有id(散列键)和accountId(范围键) 是否可以在不进行扫描的情况下进行查询以查找类别6和accountId 1中的所有产品?或者我可以用其他方法来模拟它吗 如果它是一个关系数据库,我将有一个product to category表,并连接这

我在DynamoDb中有一个简单的“产品””表。每个产品都有一个
categories
属性,该属性是一组类别ID,如下所示:

[{ "N" : "4" },{ "N" : "5" },{ "N" : "6" },{ "N" : "8" }]
产品表具有
id
(散列键)和
accountId
(范围键)

是否可以在不进行扫描的情况下进行查询以查找类别6和accountId 1中的所有产品?或者我可以用其他方法来模拟它吗


如果它是一个关系数据库,我将有一个product to category表,并连接这些产品。如果我在Dynamo中有一个类似的表,那么我需要为product表中的每个产品创建一个GetItem,这感觉不是一个好主意?

创建另一个表,并在更新主表时更新它。实际上,无论如何,这就是RDBMS中发生的事情,只是它在后台。当Amazon为表设置二级索引时,它们基本上只是自动化了人们一直在做的事情。

从您的描述来看,实现这一点的最佳方法似乎是使用索引

您的表的结构如下所示:

[{ "N" : "4" },{ "N" : "5" },{ "N" : "6" },{ "N" : "8" }]
  • hashKey:
    id
  • rangeKey:
    accountId
  • 属性-
    类别
您将使用以下结构创建全局二级索引:

  • hashKey:
    accountId
  • rangeKey:
    id
  • 属性-
    类别
然后,您可以使用您提到的条件查询此索引:

  • accountId=1
  • 类别包含6个
  • 下面是我针对DynamoDB local编写的一个快速示例,该示例投影索引上的所有属性

    import com.amazonaws.auth.BasicAWSCredentials;
    导入com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
    导入com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
    导入com.amazonaws.services.dynamodbv2.document.DynamoDB;
    导入com.amazonaws.services.dynamodbv2.document.Index;
    导入com.amazonaws.services.dynamodbv2.document.Item;
    导入com.amazonaws.services.dynamodbv2.document.QueryFilter;
    导入com.amazonaws.services.dynamodbv2.document.Table;
    导入com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
    导入com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
    导入com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
    导入com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex;
    导入com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
    导入com.amazonaws.services.dynamodbv2.model.KeyType;
    导入com.amazonaws.services.dynamodbv2.model.Projection;
    导入com.amazonaws.services.dynamodbv2.model.ProjectionType;
    导入com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
    导入com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
    导入com.amazonaws.services.dynamodbv2.util.Tables;
    公共类堆栈溢出{
    私有静态最终字符串EXAMPLE\u TABLE\u NAME=“EXAMPLE\u TABLE”;
    私有静态最终字符串哈希_KEY=“id”;
    私有静态最终字符串范围\u KEY=“accountId”;
    私有静态最终字符串GSI=“accountIdToId”;
    私有静态最终字符串CATEGORIES=“CATEGORIES”;
    公共静态void main(字符串[]args)引发InterruptedException{
    亚马逊数据库
    客户=
    新的AmazonDynamoDBClient(新的BasicAWSCredentials(“accessKey”、“secretKey”));
    client.setEndpoint(“http://localhost:4000");
    DynamoDB DynamoDB=新DynamoDB(客户);
    if(Tables.doesTableExist(客户机,示例_TABLE_NAME)){
    client.deleteTable(示例表名称);
    }
    CreateTableRequest CreateTableRequest=新建CreateTableRequest();
    createTableRequest.withTableName(例如表名);
    createTableRequest.withKeySchema(新的KeySchemaElement(HASH_KEY,KeyType.HASH),
    新的KeySchemaElement(RANGE_KEY,KeyType.RANGE));
    createTableRequest.withAttributeDefinitions(
    新的AttributeDefinition(哈希键,ScalarAttributeType.S),
    新的属性定义(RANGE_KEY,ScalarAttributeType.S));
    createTableRequest.withProvisionedThroughput(新的ProvisionedThroughput(15l,15l));
    //GSI定义
    最终全球次级指数
    帐户ID=
    新建GlobalSecondaryIndex().withIndexName(GSI).withKeySchema(
    新的KeySchemaElement(RANGE_KEY,KeyType.HASH),
    新的KeySchemaElement(HASH_KEY,KeyType.RANGE))。带有ProvisioniedThroughput(
    带投影的新供应通路(10l,10l)(
    新建投影().withProjectionType(ProjectionType.ALL));
    createTableRequest.WithGlobalSecondary索引(AccountId);
    最终表格=dynamoDB.createTable(createTableRequest);
    table.waitForActive();
    表.putItem(新项目()
    .withPrimaryKey(散列键“1”,范围键“6”)
    .withNumberSet(类别1、2、5、6));
    表.putItem(新项目()
    .withPrimaryKey(散列键“2”,范围键“6”)
    .使用数字集(第5、6类);
    表.putItem(新项目()
    .withPrimaryKey(散列键“5”,范围键“6”)
    .使用NumberSet(类别1、2));
    表.putItem(新项目()
    .withPrimaryKey(散列键“5”,范围键“8”)
    .withNumberSet(类别1、2、6));
    System.out.println(“扫描表格,无过滤器”);
    table.scan().forEach(System.out::println);
    System.out.println();
    最终索引gsi=table.getIndex(gsi);
    System.out.println(“不带过滤器扫描GSI”);
    gsi.scan().forEach(System.out::println);
    System.out.println();
    System.out.println(“查询