私は DynamoDB を初めて使用し、次のシナリオを node.js と DynamoDB で機能させるのに問題があります。
ユーザー テーブルにユーザーを挿入したいのですが、ユーザーの電子メール アドレスが既に存在する場合は成功させたくありません。
次のコードは、新しいユーザーを正常に挿入できます。
var item = {
id: { S: uuid.v4()},
email: { S: 'my@email.com' }
};
dynamodb.putItem({
TableName: 'user',
Item: item,
Expected: {
email: { Exists: false }
}
}, function (err, data) {
if (err) {
return callback(err);
}
callback();
});
Expected 値は、ConditionalCheckFailedException エラーを発生させることで、ユーザーのテーブルで電子メール アドレスが重複するのを防ぐと想定しました。これはそうではありません; 上記のコードは重複したメールを一貫して挿入します。「id」を追加の期待フィールドとして追加しようとしましたが、これは動作を変更しませんでした。
生成された UUID ではなく ID が固定されるようにコードを変更すると、ConditionalCheckFailedException が発生します。
var item = {
id: { S: 'Test' },
email: { S: 'my@email.com' }
};
「id」はハッシュキーで、「email」は範囲キーです。
この動作により、ハッシュ キーで指定されたレコードに対してのみ制約が機能すると考えるようになりました。その場合、AWS のドキュメントは非常に紛らわしいものになります (混乱する箇所を太字で強調しました)。
Exists が false の場合、Amazon DynamoDB は属性値がテーブルに存在しないと想定します。実際に値が存在しない場合、仮定は有効であり、操作は成功します。値が見つかった場合、存在しないという前提にもかかわらず、操作は ConditionalCheckFailedException で失敗します。
ドキュメントが正しいと仮定すると、私は何か間違ったことをしているに違いありませんか? どんな助けでも大歓迎です!
編集 2013-11-09
以下のコメントに基づいて、戦術を変更することにしました。不変ではない他のほとんどのドメイン オブジェクトで参照する必要がある値を使用することに少し気が進まないのです。これで、ユーザー ID のルックアップ/インデックス テーブルとして機能する電子メール アドレス テーブルができました。これにより、ユーザーに自分の電子メール アドレスを非常に簡単に変更させることができます (複数の電子メール アドレスをサポートすることもできます)。
助けてくれてありがとう!