sql >> データベース >  >> NoSQL >> Redis

サービススタックRedisリストの更新

    リストを避ける:

    残念ながら、Redisリストはあまり良い選択ではありません この状況で。 Redisを使い始めたときも同じ問題がありましたが、当然の選択のようです;)。 Redisリストは、読み取り専用セットとして使用している場合、または単にポップしてプッシュしたいが、リストの中央にあるアイテムを変更したい場合には便利です。

    アイテムのインデックスがわかっている場合は、Redisリストのアイテムを「更新」できますが、削除する必要があります。 および再挿入 、そしてそれはインデックスによるものでなければならず、それを決定することはひどく非効率的です。これは、コレクションを反復処理することによって行われます。これは、ネイティブな方法がないためです。これはお勧めできません。これはIndexOfのスニペットです RedisClientList<T>のメソッド 。

    public int IndexOf(T item)
    {
        //TODO: replace with native implementation when exists
        var i = 0;
        foreach (var existingItem in this)
        {
            if (Equals(existingItem, item)) return i;
            i++;
        }
        return -1;
    }
    

    したがって、コードを完成させるには、次のようになります。

    public void UpdatePizza(Pizza pizza)
    {
        using (var redisClient = new RedisClient(Host, Port))
        {
            IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
            IRedisList<Pizza> pizzas = redis.Lists["pizzas:live"];
            var toUpdate = pizzas.First(x => x.Id == pizza.Id);
            toUpdate.State = pizza.State;
    
            // Update by removing & inserting (don't do it!)
            var index = pizzas.IndexOf(toUpdate);
            pizzas.Remove(index);
            pizzas.Insert(index, toUpdate);
        }                   
    }
    

    しかし、私が言ったように、これはそれを処理するための良い方法ではありません。他のピザオブジェクトのリストを取得し、インデックスと一致するまでそれらを繰り返し処理します。そして更新する2つの操作! :(この状況ではリストを避けるのが最善です。

    解決策:

    IDでピザにアクセスしようとしているので、オブジェクトごとに一意のピザキーを作成できます。これにより、ピザに直接アクセスできるようになります。したがって、次を使用する可能性があります:

    pizzas:live:{Id}
    

    例:

    ピザを作成する

    using (var redisClient = new RedisClient())
    {
        IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
        var pizzaKey = string.Format("pizzas:live:{0}", 123);
        var pizza = new Pizza { Id = 123, Type = "Mushroom", State = "Cooking" };
        redis.SetEntry(pizzaKey, pizza);
    }
    

    Idでピザを入手

    using (var redisClient = new RedisClient())
    {
        IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
        var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
        var pizza = redis.GetValue(pizzaKey);
    }
    

    Idでピザを更新 (単にGETとSET)

    using (var redisClient = new RedisClient())
    {
        IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
        var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
        var pizza = redis.GetValue(pizzaKey); // Get
        pizza.State = "Delivery"; // Update
        redis.SetEntry(pizzaKey, pizza); // Save
    }
    

    別の「リスト」に移動 (たぶん:ピザの状態が変わったとき)

    using (var redisClient = new RedisClient())
    {
        var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
        var deliveredKey = string.Format("pizzas:delivered:{0}", pizza.Id);
        redisClient.RenameKey(pizzaKey, deliveredKey);
    }
    

    ピザを削除する

    using (var redisClient = new RedisClient())
    {
        var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
        redisClient.Remove(pizzaKey);
    }
    

    すべてのライブピザを一覧表示する

    using (var redisClient = new RedisClient())
    {
        var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
        List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
    }
    

    これがお役に立てば幸いです。




    1. Meteorのユニークなクライアントサイドコレクションのパブリッシュ/サブスクライブ戦略

    2. NestJS:セッションベースのユーザー認証を実装する方法

    3. Mongoidを使用したバッチ挿入/更新?

    4. MongoDB-テキストフィールドのインデックスとテキストインデックスの違いは?