如何使用非主键字段查询 DynamoDB?
How do I query DynamoDB with non primary key field?
我的 dynamoDB 中有以下数据 table。
这是我的代码:
const userStatusParams = {
TableName: process.env.USERSTATUS_TABLE,
KeyConditionExpression: "loggedIn = :loggedIn",
ExpressionAttributeValues: {
":loggedIn": true
}
};
var usersResult;
try {
usersResult = await dynamoDbLib.call("query", userStatusParams);
console.log(usersResult);
}catch (e) {
console.log("Error occurred querying for users belong to group.");
console.log(e);
}
亚马逊 return 返回此错误:
{ ValidationException: Query condition missed key schema element: userId
at Request.extractError ...
我如何获得 return loggedIn == true 的所有记录?
我的数据库目前通过我的 serverless.yml 配置结构如下。
phoneNumberTable: #This table is used to track phone numbers used in the system.
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:custom.phoneNumberTable}
AttributeDefinitions: #UserID in this case will be created once and constantly updated as it changes with status regarding the user.
- AttributeName: phoneNumber
AttributeType: S
KeySchema:
- AttributeName: phoneNumber
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: ${self:custom.dynamoDbCapacityUnits.${self:custom.pstage}}
WriteCapacityUnits: ${self:custom.dynamoDbCapacityUnits.${self:custom.pstage}}
我通过其他答案对此进行了一些研究,但无法弄清楚我的情况。在其他答案中,他们有排序键,但我在这里不使用排序键。
为了查询 DynamoDB table,您只能查询属于主键或索引一部分的属性。
主键可以是:
- Partition/Hash 键,或
- Partition/Hash 键和一个 Sort/Range 键
除了Primary Key,还可以创建两种类型的索引:
- 本地二级索引,其中使用相同的分区键但具有不同的排序键,或者
- 全局二级索引,其中分区键和排序键都不同。
为了查询登录记录,您需要在主键中包含此属性,或者添加包含登录属性的本地或全局二级索引。
如果你正在做 query
那么你必须传递主键,在你的情况下是 userId
。如果您没有 primaryKey
并且想要所有 logged in = true
字段,那么您可以像这样 filterExpression
和 scan
const userStatusParams = {
TableName: process.env.USERSTATUS_TABLE,
FilterExpression: 'loggedIn = :loggedIn',
ExpressionAttributeValues: {
":loggedIn": true
}
};
var usersResult;
try {
// Do scan
usersResult = await dynamoDbLib.call("scan", userStatusParams);
console.log(usersResult);
}catch (e) {
console.log("Error occurred querying for users belong to group.");
console.log(e);
}
更新: 由于scan
操作效率较低,解决这个问题的另一种方法是创建一个GSI
,主键loggedIn
。但是这里的问题是你不能创建任何具有 boolean
data type. 的字段主键。它必须是 number, string, binary
。因此,要创建 gsi
,您需要将接受的数据类型存储在 loggedIn
字段中,而不是 boolean
。
虽然我不确定它会对 table 千条记录产生多大的性能影响,但 gsi
的好处是您可以创建它们 later even on the existing table 如果未来你会发现一些性能影响。此外,您可以在 table 上创建的 gsi
数量限制为 5
。所以明智地利用 gsi
。
扫描操作始终扫描整个 table 或二级索引,然后过滤掉值以提供所需的结果,本质上是添加从结果集中删除数据的额外步骤。如果可能,请避免对大型 table 或带有删除许多结果的过滤器的索引使用扫描操作。 Read more
你应该使用全局二级索引!
AWS 控制台 > DynamoDb > table 的选项卡索引 > 创建索引 >
primary key - loggedIn
secondary key - userId
projected attributes - all
我们应该添加辅助键以获得唯一的对。不要使用索引名称 (loggedIn),因为 loggedIn 应该是唯一的。
你可以使用带有主键的查询方法 (loggedIn)
我的 dynamoDB 中有以下数据 table。
这是我的代码:
const userStatusParams = {
TableName: process.env.USERSTATUS_TABLE,
KeyConditionExpression: "loggedIn = :loggedIn",
ExpressionAttributeValues: {
":loggedIn": true
}
};
var usersResult;
try {
usersResult = await dynamoDbLib.call("query", userStatusParams);
console.log(usersResult);
}catch (e) {
console.log("Error occurred querying for users belong to group.");
console.log(e);
}
亚马逊 return 返回此错误:
{ ValidationException: Query condition missed key schema element: userId
at Request.extractError ...
我如何获得 return loggedIn == true 的所有记录?
我的数据库目前通过我的 serverless.yml 配置结构如下。
phoneNumberTable: #This table is used to track phone numbers used in the system.
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:custom.phoneNumberTable}
AttributeDefinitions: #UserID in this case will be created once and constantly updated as it changes with status regarding the user.
- AttributeName: phoneNumber
AttributeType: S
KeySchema:
- AttributeName: phoneNumber
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: ${self:custom.dynamoDbCapacityUnits.${self:custom.pstage}}
WriteCapacityUnits: ${self:custom.dynamoDbCapacityUnits.${self:custom.pstage}}
我通过其他答案对此进行了一些研究,但无法弄清楚我的情况。在其他答案中,他们有排序键,但我在这里不使用排序键。
为了查询 DynamoDB table,您只能查询属于主键或索引一部分的属性。
主键可以是:
- Partition/Hash 键,或
- Partition/Hash 键和一个 Sort/Range 键
除了Primary Key,还可以创建两种类型的索引:
- 本地二级索引,其中使用相同的分区键但具有不同的排序键,或者
- 全局二级索引,其中分区键和排序键都不同。
为了查询登录记录,您需要在主键中包含此属性,或者添加包含登录属性的本地或全局二级索引。
如果你正在做 query
那么你必须传递主键,在你的情况下是 userId
。如果您没有 primaryKey
并且想要所有 logged in = true
字段,那么您可以像这样 filterExpression
和 scan
const userStatusParams = {
TableName: process.env.USERSTATUS_TABLE,
FilterExpression: 'loggedIn = :loggedIn',
ExpressionAttributeValues: {
":loggedIn": true
}
};
var usersResult;
try {
// Do scan
usersResult = await dynamoDbLib.call("scan", userStatusParams);
console.log(usersResult);
}catch (e) {
console.log("Error occurred querying for users belong to group.");
console.log(e);
}
更新: 由于scan
操作效率较低,解决这个问题的另一种方法是创建一个GSI
,主键loggedIn
。但是这里的问题是你不能创建任何具有 boolean
data type. 的字段主键。它必须是 number, string, binary
。因此,要创建 gsi
,您需要将接受的数据类型存储在 loggedIn
字段中,而不是 boolean
。
虽然我不确定它会对 table 千条记录产生多大的性能影响,但 gsi
的好处是您可以创建它们 later even on the existing table 如果未来你会发现一些性能影响。此外,您可以在 table 上创建的 gsi
数量限制为 5
。所以明智地利用 gsi
。
扫描操作始终扫描整个 table 或二级索引,然后过滤掉值以提供所需的结果,本质上是添加从结果集中删除数据的额外步骤。如果可能,请避免对大型 table 或带有删除许多结果的过滤器的索引使用扫描操作。 Read more
你应该使用全局二级索引!
AWS 控制台 > DynamoDb > table 的选项卡索引 > 创建索引 >
primary key - loggedIn
secondary key - userId
projected attributes - all
我们应该添加辅助键以获得唯一的对。不要使用索引名称 (loggedIn),因为 loggedIn 应该是唯一的。
你可以使用带有主键的查询方法 (loggedIn)