QA@IT

redisの検索について

5959 PV

例えば、redisのHash型に最終更新日時を入れて、
10分以上経過したものを取り出すみたいな事は出来るのでしょうか?

node.jsを使ってます。

よろしくお願い致します。

回答

主に自分の勉強のために書いてみました。

kennさんのおっしゃるようにDB事に性質がありますので、より適したものを使ったほうがいいでしょう。
あくまで書いてみたら動きました程度のコードです。

  • パフォーマンスその他は考慮してません。
  • ホントに10分後という条件にすると結果でなくなるので条件は適当に変えてます。
  • 1000で割ったり調整しているのは、redisのtimeは10桁でnodejsのDateは13桁で来るためです。
  • Windows 8 64bit, Redis 2.6.12, node.js 0.9.4 です。

Hash型のみ keysでスキャン

var redis = require("redis"),
    client = redis.createClient();


function addUser(key, json){
    client.time(
        function(err, obj){
            json.updated_at = obj[0];
            client.HMSET(key, json);
        });
}

function searchHash(){
    addUser("user1", { "name": "flied", "age":"forever 18"});
    addUser("user2", { "name": "onion", "sex":"male"});

    client.keys("user*", function(err, obj){
        obj.forEach(function(reply,i){
            client.HGETALL(reply, function(err, item){
                // 10 分後ならこう
                // if(item.updated_at * 1000 > (Date.now() + 10 * 60 * 1000)){
                //     console.dir(item);
                // }

                if(item.updated_at * 1000 < (Date.now() + 10 * 60 * 1000)){
                    console.dir(item);
                }

            });
        });
        client.quit();
    });
}

searchHash();

sortedsetを併用

var redis = require("redis"),
    client = redis.createClient();


function addUser(key, json){
    client.time(
        function(err, obj){
            client.HMSET(key, json);
            client.zadd("updated_at", obj[0], key ); // append to sortedset
        });
}

function searchHash(){
    addUser("user1", { "name": "flied", "age":"forever 18"});
    addUser("user2", { "name": "onion", "sex":"male"});

    // 10 分後ならこう
    // client.zrangebyscore("updated_at", (Date.now() + 10 * 60 * 1000) / 1000 , "+inf",
    client.zrangebyscore("updated_at", (Date.now() - 10 * 60 * 1000) / 1000 , "+inf",
        function(err, obj){
            obj.forEach(function(reply, i){
                client.HGETALL(reply, function(err, item){
                    console.dir(item);
                });  
            });
            client.quit();
        });
}

searchHash();
編集 履歴 (0)
  • わざわざ試して頂きありがとうございます。
    参考になりました。
    -
  • いえ、こちらこそ勉強になりました。 あ、zrangebyscoreの10分後の方、条件がおかしいかもしれませんので注意してください(^_^; -

redisにはキー以外で検索する手段はありません。全件スキャンするしかないです。

トランザクション + sorted setなどを使って自前でインデックスを保持してやれば、一応それっぽいことはできますが、それはまるで自分でデータベースシステムをイチから作っているようなものであり、本末転倒だと言えます。

そのような用途には普通にインデックスが使えるRDBやMongoDBなどを使うのが一番だと思います。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。