2012-12-12 5 views
6

メディアオブジェクトを保存し、特定の時間範囲で取得できるようにしようとしています。私はこれを行うためにソートされたセットデータ型を選択しました。私は以下のような要素を追加しています:ソートされたセットの一意性を保証する

zAdd: key: media:552672 score: 1355264694 
zAdd: key: media:552672 score: 1355248565 
zAdd: key: media:552672 score: 1355209157 
zAdd: key: media:552672 score: 1355208992 
zAdd: key: media:552672 score: 1355208888 
zAdd: key: media:552672 score: 1355208815 

ここで、キーはメディアが取得された位置IDに固有で、スコアはメディアオブジェクトの作成時間です。その値はメディアオブジェクトのjson_decodeです。

zRevRangeByScoreを使用して検索すると、重複したエントリが表示されることがあります。私は本質的に外部APIへのバッファとしてRedisを使用しています。ユーザーが同じAPI呼び出しをX秒間に2回行っている場合は、キャッシュから結果を取得します。そうでなければ、キャッシュに追加します重複を含まないセットの定義のためにすでに存在しているかどうかを確認します。 可能な既知の問題: キャッシュ間でメディアオブジェクト属性が変更された場合、複製として表示されます

redisクライアント側でチェックを行わないとこのタイプのデータを保存する方が良いでしょうか?

TLDR; タイムスタンプでオブジェクトの範囲を選択してそれらが一意であることを確認できる、Redisのオブジェクトを格納および取得する最良の方法は何ですか?

答えて

23

はので、ここで、私たちは同じことを話していることを確認しましょセットソートのRedisのための用語です:

ZADD key score member [score] [member] 
summary: Add one or more members to a sorted set, or update its score if it already exists 
  • keyを - ソートの 'name' が
  • scoreを設定します - スコア(この場合はタイムスタンプ)
  • member - スコアが関連付けられている文字列
  • ソートされたセットには、スコアを持つメンバーが多数あります

JSONでエンコードされたオブジェクトの文字列をメンバーとして使用しているようです。メンバは、ソートされたセットで一意です。あなたが言うように、オブジェクトが変更された場合、ソートされたセットに新しいメンバーとして追加されます。それはおそらくあなたが望むものではありません。

ソートセットは、データをタイムスタンプで保存するRedisの方法ですが、セットに格納されているメンバーは通常、Redisの別のキーへの 'ポインタ'です。私はあなたがこのデータ構造をしたいと思うあなたの説明から、

  • Aが作成したタイムスタンプ
  • によってそれぞれのユニークなメディア

のための文字列またはハッシュをすべてのメディアを格納し、私は保存をお勧めしますソートこのようにメディアオブジェクトをハッシュ形式にすることで、より柔軟な操作が可能になります。 例:

# add some members to our sorted set 
redis 127.0.0.1:6379> ZADD media 1000 media:1 1003 media:2 1001 media:3 
(integer) 3 
# create hashes for our members 
redis 127.0.0.1:6379> HMSET media:1 id 1 name "media one" content "content string for one" 
OK 
redis 127.0.0.1:6379> HMSET media:2 id 2 name "media two" content "content string for two" 
OK 
redis 127.0.0.1:6379> HMSET media:3 id 3 name "media three" content "content string for three" 
OK 

このように保存されたデータを取得するには2つの方法があります。特定のタイムスタンプ範囲(たとえば、過去7日間)内にメンバーを取得する必要がある場合は、ZREVRANGEBYSCOREを使用してメンバーを取得してから、各ハッシュをHGETALLなどとフェッチするためにそれらをループする必要があります。サーバーへの1回の呼び出しでループを実行する方法については、pipeliningを参照してください。

redis 127.0.0.1:6379> ZREVRANGEBYSCORE media +inf -inf 
1) "media:2" 
2) "media:3" 
3) "media:1" 
redis 127.0.0.1:6379> HGETALL media:2 
1) "id" 
2) "2" 
3) "name" 
4) "media two" 
5) "content" 
6) "content string for two" 

あなただけの最後のnメンバー(または、例えば:10最近のほとんどの生誕100に最新)を取得したい場合は、アイテムを取得するためにSORTを使用することができます。構文と異なるハッシュフィールドを取得し、結果やその他のオプションを制限する方法については、sort documentationを参照してください。

redis 127.0.0.1:6379> SORT media BY nosort GET # GET *->name GET *->content1) DESC 
1) "media:2" 
2) "media two" 
3) "content string for two" 
4) "media:3" 
5) "media three" 
6) "content string for three" 
7) "media:1" 
8) "media one" 
9) "content string for one" 

NB:のみのRedis 2.6から作品スコア(BY nosort)でソートされたハッシュをソートします。

最後の日、週、月などのメディアを取得する予定がある場合は、それぞれに個別のソートセットを使用し、古いメンバーを削除するのにZREMRANGEBYSCOREを使用することをお勧めします。これらのソートセットでSORTを使用するだけで、データを取得できます。

+0

ありがとう、私は正確なものを探していた。簡単な質問:私は重複したくない状況があるので、ソートされたセットでそれらをチェックし、それらを追加してハッシュを作成しています。私はそれが過度のものかどうか尋ねたがっていますか? –

関連する問題