【问题标题】:How can i use Parallel Scan of AWS DynamoDB to run scan on a specific GSI?如何使用 AWS DynamoDB 的并行扫描在特定 GSI 上运行扫描?
【发布时间】:2021-01-08 08:41:19
【问题描述】:

我有一个 DynamoDB 表,其中每个项目都有一个名为“DataType”的键。 此表上还有一个 GSI,此“DataType”作为 HashKey,“timestamp”作为 rangeKey。

大约 10% 的表格项的“DataType”值为“A”。

我想扫描此 GSI 的所有项目,并将 HashKey 固定为“A”。有没有办法使用扫描/并行扫描来执行此操作?还是我需要对 GSI 本身使用查询来执行此操作?

根据文档, https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/spec/ScanSpec.html

我找不到任何方法来指定我可以使用固定的 HashKey 扫描的 GSI。

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb dynamodb-queries amazon-dynamodb-index secondary-indexes


    【解决方案1】:

    鉴于您只想查看带有哈希键“A”的项目,您需要使用 Query API 而不是 Scan API,提供索引名称,并在索引中查询具有该名称的项目分区键。

    下面是一些使用Node AWS SDK V3 的示例代码,它在具有全局二级索引(称为GSI1)的表中创建三个项目。其中两个项目的GSI1PK 值为"orange",而另一个项目的GSI1PK 值为"gold"。查询返回两个匹配项:

        const tableName = getFromEnv(`TABLE_NAME`);
        const client = new DynamoDBClient({});
    
        async function createItem(
            name: string,
            PK: string,
            SK: string,
            GSI1PK: string,
            GSI1SK: string,
        ): Promise<void> {
            const item = { PK, SK, GSI1PK, GSI1SK, name };
            const putCommand = new PutItemCommand({
                TableName: tableName,
                Item: marshall(item)
            });
            await client.send(putCommand);
            log(`Created item: ${name} with GSI1PK ${GSI1PK}`);
        }
    
        await createItem(`foo`, `fooPK`, `fooSK`, `orange`, `blue`);
        await createItem(`bar`, `barPK`, `barSK`, `orange`, `white`);
        await createItem(`baz`, `bazPK`, `bazSK`, `gold`, `garnet`);
    
        log(`Waiting 5 seconds, as GSIs don't support consistent reads`)
        await wait(5);
    
        const query: QueryCommandInput = {
            TableName: tableName,
            IndexName: `GSI1`,
            KeyConditionExpression: `#pk = :pk`,
            ExpressionAttributeNames: {
                '#pk': `GSI1PK`,
            },
            ExpressionAttributeValues: {
                ':pk': { S: `orange` },
            },
        }
    
        const result = await client.send(new QueryCommand(query));
        log(`Querying GSI1 for "orange"`);
        result.Items.forEach((entry) => {
            log(`Received: `, unmarshall(entry).name);
        });
    

    这会产生以下输出:

    Created item: foo with GSI1PK orange
    Created item: bar with GSI1PK orange
    Created item: baz with GSI1PK gold
    Waiting 5 seconds, as GSIs don't support consistent reads
    Querying GSI1 for "orange"
    Received:  foo
    Received:  bar
    

    此示例中值得注意的一点是 GSI 不允许一致性读取。因此,如果您的用例需要立即保持一致性,您将需要寻找其他解决方案。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多