前回紹介したRedisのLIST型に続き,
SET型の構造
RedisのSET型は,
LIST型のPUSHやPOPと同様,
一見,
実は,
集合演算
SET型には3種類の集合演算コマンドが用意されています。積集合
上図では2つのセット間の演算を示していますが,
また,
SET型を使ったタグ検索
SET型の基本操作にひと通り触れてみるために,
各タグごとに,
基本的なタグの操作は,
<?php
// タグにコンテンツIDを関連付ける
function tagset_add($tag_id, $content_id) {
$redis = new Redis();
$redis->connect('localhost', 6379);
$redis->sAdd('tag:' . $tag_id, $content_id);
$redis->close();
}
// タグとコンテンツIDの関連を削除する
function tagset_remove($tag_id, $content_id) {
$redis = new Redis();
$redis->connect('localhost', 6379);
$redis->sRemove('tag:' . $tag_id, $content_id);
$redis->close();
}
// タグに関連するコンテンツIDを収得する
function tagset_contents($tag_id) {
$redis = new Redis();
$redis->connect('localhost', 6379);
$mems = $redis->sMembers('tag:' . $tag_id);
$redis->close();
return $mems;
}
SETへの要素の追加はSADDコマンド,
次に,
SINTER tag:dance tag:sing
実際のアプリケーションではもう少し後処理が必要になるかもしれません。例えば,
SINTERSTORE tmpset tag:dance tag:sing SDIFF tmpset tag:r18
SINTERSTOREコマンドで,
以上のコマンド操作をプログラムで実装すると次のようになります。なお,
<?php
function tagset_search($tag_id1, $tag_id2) {
$redis = new Redis();
$redis->connect('localhost', 6379);
// 指定されたタグのAND検索結果をtmpset1に格納
// SINTERSTORE tmpset1 タグ1 タグ2
$tmpset1 = /*適当なテンポラリキーを生成*/;
$redis->sInterStore($tmpset1,
'tag:' . $tag_id1,
'tag:' . $tag_id2);
// R18タグに関連するコンテンツを除外してtmpset2に格納
// SDIFFSTORE tmpset2 tmpset1 tag:r18
$tmpset2 = /*適当なテンポラリキーを生成*/;
$redis->sDiffStore($tmpset2, $tmpset1, 'tag:r18');
// アクセス数の多い順にソート
// SORT tmpset2 BY access_count:* DESC
$result = $redis->sort($tmpset2,
array('sort'=>'desc', 'by'=>'access_count:*'));
$redis->close();
return $result;
}
前回,
容量の問題
上記の手法によるタグ検索の問題は,
本来であればRedis VMによってある程度解決できる問題であったはずですが,
ただし,