2016-05-09 7 views
1

でのソート・キーを使用しての「インデックスキーの型の不一致」私は、次のインデックスを持つテーブルがあります。DynamoDBの

  • ユーザー
    • ID(文字列、プライマリー)
    • メール(文字列を、グローバルセカンダリ)
    • expiresOn(日付(文字列)、グローバルセカンダリ)
    • is_premium(ブール値)

私はis_premiumexpiresOnの範囲/ソート・キーも持っているしたいと思いますので、私は例えば今日の日付の前または上の有効期限が切れているすべてのアカウントを照会し、そのis_premium =真を持つことができます。

今日の前/次で期限切れになっているすべてのアカウントをis_premium = trueではなく照会しただけで、結果の90%がテーブルに表示されます。

しかし、私はis_premium上で範囲クエリを設定しようとした場合、私はテーブルにレコードを保存しようとすると、私は次のエラーを取得する:

com.amazonaws.AmazonServiceException:インデックスキーの型の不一致を (サービス:NULL;ステータスコード:400;エラーコード:にValidationException; リクエストID:ヌル)

com.amazonaws.services.dynamodbv2.local.embedded.DDBExceptionMappingInvocationHandler.handleDynamoDBLocalServiceExceptionで(DDBExceptionMappingInvocationHandler.java:76) at com.amazonaws.services.dynamodbv2.local.embedded.DDBExceptionMappingInvocationHandler.invoke(DDBExceptionMappingInvocationHandler.java:58) (com.sun.proxy)$ Proxy70.putItem(不明なソース)at com.amazonaws.services.dynamodbv2 .datamodeling.DynamoDBMapper $ SaveObjectHandler.doPutItem(DynamoDBMapper.java:1270) でcom.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper $ 1.executeLowLevelRequest(DynamoDBMapper.java:879) com.amazonaws.services.dynamodbv2で。 datamodeling.DynamoDBMapper $ SaveObjectHandler.execute(DynamoDBMapper.java:1120) でcom.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:966) で10 com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:758)

私は、ソート/レンジキーを削除した場合、すべての作品dynamoDbMapper.save(order)

でこれを取得します。

私が間違っていることは何ですか?エラーは非常に曖昧です。

答えて

1

dynamodbのハッシュ/範囲キーのブールフィールドはサポートされていません。 (文字列/数値/バイナリのみがサポートされています)。

STRINGまたはNUMBERに変換する(または新しい列を追加する)必要があります。 (これがあなたの範囲キーであるならば、それは 'true'/'false'または0/1になります)。それがあなたのハッシュキーだったらもっと複雑になります。

+0

プレミアムにローカルのセカンダリインデックスを使用するなどの回避策がありますか? –

+0

ブール値の代わりに0または1を使うのはどうですか? – birnbaum

+0

@birnbaumそれはブール値を使用するだけでJavaの型安全性機能とうまく機能します。 –

1

ブーリアンはDynamoDBの有効なハッシュ/範囲キーではありません。あなたが提案したアーキテクチャーを作るための可能な解決策は、ブール値を0と1にマッピングするようにデータマッパーを変更することです。

しかし、この方法で特定の有効期限を照会して、か否か。私があなたのユースケースを正しく理解していれば、あなたが欲しいものはすべてで、特定のexpiresOn時間枠内にあります。この場合の好ましいアーキテクチャは次のようになります。

グローバルセカンダリ・パーティションキー
  • expiresOnとして
    • is_premiumグローバルセカンダリソートなどの主要

    あなたがis_premiumパーティションを照会し、並べ替えを使用することができます。この方法例えばこのパーティション内の1日以内に期限切れになるすべての項目を除外します。

  • +0

    GSIを 'is_premium'と' expiresOn'に置くのにパフォーマンス上の利点はありますか? –

    +1

    明確にする:GSIはパーティションとソートキーで構成されています。 DynamoDBでクエリを実行するときは、常に正確なパーティションキー値を提供する必要があります。つまり、 'expiresOn'があなたのパーティションキーである場合、このGSIのクエリは非常に特殊な' expiresOn'値を含む必要があり、範囲や何かを含めることはできません。これは 'expiresOn'があなたのソートキーでなければならない理由です。 – birnbaum

    +0

    私は参照してください。それはたくさん説明します。うーん、私は 'premium = true'のレコードだけを含む新しいテーブルを作成してしまい、' expiresOn <=:val'を実行するフィルターでスキャンしています。それはどのようにこれに匹敵するのですか?このようにする方が効率的ですか? –