我如何使用 AWS DynamoDB 的并行扫描对特定 GSI 进行 运行 扫描?
How can i use Parallel Scan of AWS DynamoDB to run scan on a specific GSI?
我有一个 DynamoDB table,其中每个项目都有一个名称为 'DataType' 的键。
此 table 上还有一个 GSI,此 'DataType' 作为 HashKey,'timestamp' 作为 rangeKey。
table 项中大约 10% 的 'DataType' 值为 'A'。
我想扫描此 GSI 的所有项目,HashKey 固定为 'A'。有什么方法可以使用 scan/parallel 扫描来执行此操作?或者我是否需要在 GSI 本身上使用查询来执行此操作?
我找不到任何方法来指定我可以在其上使用固定 HashKey 进行扫描的 GSI。
鉴于您只想查看具有哈希键“A”的项目,您需要使用查询 API 而不是扫描 API,提供索引名称,并查询索引中具有该分区键的项目。
下面是一些使用 Node AWS SDK V3 的示例代码,它在 table 中使用全局二级索引(称为 GSI1
)创建了三个项目。其中两项的 GSI1PK
值为 "orange"
,而另一项的 GSI1PK
值为 "gold"
。查询returns匹配的两个:
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 不允许一致读取。因此,如果您的用例需要即时一致性,您将需要寻找其他解决方案。
我有一个 DynamoDB table,其中每个项目都有一个名称为 'DataType' 的键。 此 table 上还有一个 GSI,此 'DataType' 作为 HashKey,'timestamp' 作为 rangeKey。
table 项中大约 10% 的 'DataType' 值为 'A'。
我想扫描此 GSI 的所有项目,HashKey 固定为 'A'。有什么方法可以使用 scan/parallel 扫描来执行此操作?或者我是否需要在 GSI 本身上使用查询来执行此操作?
我找不到任何方法来指定我可以在其上使用固定 HashKey 进行扫描的 GSI。
鉴于您只想查看具有哈希键“A”的项目,您需要使用查询 API 而不是扫描 API,提供索引名称,并查询索引中具有该分区键的项目。
下面是一些使用 Node AWS SDK V3 的示例代码,它在 table 中使用全局二级索引(称为 GSI1
)创建了三个项目。其中两项的 GSI1PK
值为 "orange"
,而另一项的 GSI1PK
值为 "gold"
。查询returns匹配的两个:
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 不允许一致读取。因此,如果您的用例需要即时一致性,您将需要寻找其他解决方案。