如何使用非主键字段查询DynamoDB?

我在我的dynamoDB表中有以下数据。

在这里输入图像说明

这是我的代码:

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); } 

亚马逊返回这个错误:

 { ValidationException: Query condition missed key schema element: userId at Request.extractError ... 

我怎样才能返回logging在所有logging==真?

我的数据库目前是通过我的serverless.ymlconfiguration来构build的。

 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}} 

我通过其他答案对此做了一点研究,但无法弄清楚我的情况。 在其他答案他们有sorting键,但我不在这里使用sorting键。

如果你正在query那么你必须通过主键,在你的情况是userId 。 如果你没有primaryKey ,如果你想所有的logged in = true字段,那么你可以做这样的primaryKey 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操作效率较低,解决此问题的另一种方法是创build一个GSI ,主键loggedIn 。 但是这里的问题是你不能创build任何具有boolean数据types的字段主键。 。 它必须是number, string, binary 。 所以要创build一个gsi你需要将接受的数据types存储在loggedIn字段而不是boolean

虽然我不确定会有多less性能影响它将有一千张logging表,但关于gsi是,如果将来您发现一些性能影响,您可以在以后创build它们。 此外,您可以在桌面上创build的gsi数量限制为5 。 所以明智地利用gsi

扫描操作总是扫描整个表或二级索引,然后筛选出值以提供所需的结果,基本上增加了从结果集中移除数据的额外步骤。 如果可能,避免在大型表格或索引上使用扫描操作,并使用filter删除多个结果。 阅读更多

你应该使用全局二级索引!

AWS控制台> DynamoDb>选项卡您的表的索引>创build索引>

 primary key - loggedIn secondary key - userId projected attributes - all 

我们应该添加二级密钥来拥有唯一的对。 不要使用索引名称(loggedIn),以便login应该是唯一的。

你可以使用主键(loggedIn)的Query方法

为了查询dynamodb表,您只能查询索引字段。 索引字段可以是:

  1. 首要的关键
  2. 二级全局索引散列

为了查询loggedInlogging,您需要在loggedIn字段中添加全局二级索引。

我不会这样做你的数据,因为所有loginlogging有2个值(真/假),这将导致许多吞吐量错误,除非你有高容量。 (你将永远有“热门”的密钥,由于分区上散列错误而导致的)

如果你仍然想在dynamodb上使用这个查询,你应该改变'loggedIn'值,以防止'热'键

解决办法是给你的数据添加一些后缀:(true.0,true.1 … true.N)

N应该是[这个指数的预期分区+一些增长差距](如果你期望高负荷,或许多“真/假”,那么你可以selectN = 200)(对于分区上的一个好的散列分布)。 我build议N将模仿userId。 (这可以帮助你做一些userId操作。)