2

現在、次のフィールドを含むコレクションがあります。

  • userId
  • otherUserId
  • date
  • status

Dynamo コレクションでは、userId を としてhashKey使用し、 rangeKeydate:otherUserId を使用したいと考えていました。このようにすることで、良い日付でソートされたすべての userId エントリを取得できました。

ただし、私のユースケースでは、重複があってはなりません。つまりuserId-otherUserId、コレクションに同じ値を持つべきではありません。つまり、最初にクエリを実行してその「カップル」が存在するかどうかを確認し、必要に応じて削除してから挿入する必要がありますよね?

編集:

すでにご協力いただきありがとうございます:-)

私のユースケースの目標は、userA が userB のプロファイルにアクセスしたときに保存することです。

今、私がやりたい種類のクエリは次のとおりです。

  • UserA のプロファイルにアクセスしたすべての UserB を、一意 (= UserB が重複していない) で、時間順に並べ替えて取得します。
  • UserA と UserB の特定のペアの訪問を取得する
4

1 に答える 1

2

多くの選択肢があると思いますが、ここでは、アプリケーションが時間を認識しているという前提に基づいて機能する可能性のあるものを示します。つまり、過去 N 分、時間、日などの相互作用を照会したいということです。

hash_key = userA
range_key = [iso1860_timestamp][1]+userB+uuid

まず、uuid のトリックは、userA と userB の間の対話がまったく同時に発生した記録を上書きしないようにするためのものです (時計の粒度/精度によっては発生する可能性があります)。したがって、挿入に関しては安全です。重複も上書きもありません。

クエリに関しては、次のように処理が行われます。

  • UserA のプロファイルにアクセスしたすべての UserB を、一意 (= UserB が重複していない) で、時間順に並べ替えて取得します。

query(hash_key=userA, range_key_condition=BEGIN(common_prefix))

where common_prefix= 2013 年 1 月のすべてのインタラクションに対して 2013-01-01

これにより、時間範囲内のすべてのレコードがソートされて取得されます (適切な順序で挿入されたと仮定します)。次に、アプリケーション コードでそれらをフィルタリングして、userB に関するものだけを保持します。残念ながら、DynamoDB API は範囲キー条件のリストをサポートしていません (それ以外の場合は、追加の CONTAINS userB 条件を渡すことで時間を節約できます)。

  • UserA と UserB の特定のペアの訪問を取得する

query(hash_key=userA, range_key_condition=BEGINS(common_prefix))

common_prefixインタラクションのタイムスタンプを知っていると仮定できる場合、どこでより正確になる可能性があります。

もちろん、この設計は、処理するデータ ストリームのプロパティに関して評価する必要があります。(ほとんどの場合) クエリに意味のある時間範囲を指定できる場合、それは高速であり、userA の時間範囲で記録したインタラクションの数によって制限されます。

アプリケーションがそれほど時間指向でない場合 (ユーザーはほとんどの場合少数の対話しか行わないと想定できます)、次のスキーマに切り替えることができます。

hash_key = userA
range_key = userB+[iso1860_timestamp][1]+uuid

このようにして、ユーザーごとにクエリを実行できます。

query(hash_key=userA, range_key_condition=BEGIN(userB))

この代替手段は高速であり、すべての時間範囲でのユーザー A とユーザー B のやり取りの数によって制限されます。これは、アプリケーションによっては意味がある場合があります。

したがって、基本的にはサンプル データを確認し、アプリケーションにとって意味のある向きを推定する必要があります。両方の方向性 (時間またはユーザー) は、他のテーブルに手動でインデックスを作成して維持することによっても高速化される可能性がありますが、より複雑なアプリケーション コードが必要になります。


(歴史的なバージョン:時間ベースのキーでレコードを上書きしないようにするためのトリック)あなたの場合の一般的なトリックは、生成された一意のID(uuid)で範囲キーを後置することです。このようにして、特定の期間に挿入されたレコードを取得する条件付きのquery呼び出しを引き続き行うことができ、挿入時のキーの衝突について心配する必要はありません。BETWEEN

于 2013-03-27T13:07:12.650 に答える