繁体   English   中英

如何使用 AWS DynamoDB 的并行扫描对特定 GSI 运行扫描?

[英]How can i use Parallel Scan of AWS DynamoDB to run scan on a specific GSI?

我有一个 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。

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

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

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

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

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

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

下面是一些使用节点 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);
    });

这会产生 output:

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 不允许一致读取。 因此,如果您的用例需要即时一致性,您将需要寻找其他解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM