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);
}
Amazonはこのエラーを返します:
{ ValidationException: Query condition missed key schema element: userId
at Request.extractError ...
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}}
私は他の答えを介してこれについて少し調査しましたが、私の状況を理解することができませんでした。他の回答では、ソートキーがありましたが、ここではソートキーを使用しません。
query
を実行している場合は、主キー(この場合はuserId
)を渡す必要があります。 primaryKey
がなく、すべてのlogged in = true
フィールドが必要な場合は、次のようにscan
を使用してfilterExpression
を実行できます。
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
操作の効率が低いため、この問題を解決するもう1つの方法は、GSI
を作成することです。 、主キーloggedIn
を使用します。ただし、ここでの問題は、 boolean
データ型。 を持つフィールドの主キーを作成できないことです。 number, string, binary
である必要があります。したがって、gsi
を作成するには、受け入れられたデータ型をloggedIn
ではなくboolean
フィールドに格納する必要があります。
1000レコードのテーブルに対してパフォーマンスにどの程度の影響があるかはわかりませんが、gsi
の良いところは、それらを作成できることです 後で既存のテーブルでも 将来的には、パフォーマンスへの影響がわかります。また、テーブルに作成できるgsi
の数は5
に制限されています。したがって、gsi
を賢く利用してください。
スキャン操作は常にテーブル全体またはセカンダリインデックスをスキャンし、値をフィルターで除外して目的の結果を提供します。基本的に、結果セットからデータを削除するという追加の手順が追加されます。可能であれば、多くの結果を削除するフィルターを使用して、大きなテーブルまたはインデックスでスキャン操作を使用することは避けてください。 続きを読む
グローバルセカンダリインデックスを使用する必要があります!
AWSコンソール> DynamoDb>タブテーブルのインデックス>インデックスの作成>
primary key - loggedIn
secondary key - userId
projected attributes - all
一意のペアを持つために、2次キーを追加する必要があります。 loginは一意である必要があるため、インデックス名(loggedIn)は使用しないでください。
主キー(loggedIn)でQueryメソッドを使用できるより
dynamodbテーブルをクエリするには、インデックス付きフィールドでのみクエリを実行できます。インデックス付きフィールドには次のものがあります。
loggedInレコードを照会するには、loggedInフィールドにグローバルセカンダリインデックスを追加する必要があります。
すべてのloggedInレコードには2つの値(true/false)があり、大容量でない限り、これにより多くのスループットエラーが発生するため、データの場合はこれを行いません。 (パーティション間でのハッシュ分散が悪いために作成された「ホット」キーは常に存在します)
それでもdynamodbでこのクエリを使用する場合は、「ホット」キーを防ぐために「loggedIn」値を変更する必要があります
解決策は、データにサフィックスを追加することです:(true.0、true.1 ... true.N)
Nは[このインデックスに予想されるパーティション+ある程度の成長ギャップ](高負荷または多くの「true/false」が予想される場合は、N = 200を選択できます)(パーティション間での適切なハッシュ分散のため)である必要があります。 NはuserIdを法とすることをお勧めします。 (これは、userIdによる操作を行うのに役立ちます。)