Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Aktualisieren der Service Stack Redis-Liste

Listen vermeiden:

Leider sind Redis-Listen keine wirklich gute Wahl in dieser Situation. Ich hatte das gleiche Problem, als ich anfing, Redis zu verwenden, sie scheinen die offensichtliche Wahl zu sein;). Redis-Listen sind nützlich, wenn Sie sie als schreibgeschützten Satz verwenden oder wenn Sie nur Pop und Push verwenden möchten, aber nicht, um ein Element in der Mitte der Liste zu ändern.

Sie können Elemente in einer Redis-Liste "aktualisieren", wenn Sie den Index des Elements kennen, aber es muss entfernt werden und erneut einfügen , und es muss ein Index sein, dessen Bestimmung schrecklich ineffizient ist. Dies geschieht durch Iterieren der Sammlung, da es keine native Möglichkeit gibt, dies zu tun, und dies keine gute Idee ist. Dies ist ein Ausschnitt des IndexOf -Methode der 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;
}

Um Ihren Code zu vervollständigen, wäre es also:

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);
    }                   
}

Aber das ist keine schöne Art, damit umzugehen, wie ich gesagt habe. Es ruft die Liste der anderen Pizza-Objekte ab und iteriert dann über sie, bis sie mit dem Index übereinstimmt. Und zwei Operationen zum Aktualisieren! :( Vermeiden Sie in dieser Situation am besten Listen.

Lösung:

Wenn Sie versuchen, über die ID auf die Pizza zuzugreifen, können Sie für jedes Objekt einen eindeutigen Pizzaschlüssel erstellen, mit dem Sie direkt auf die Pizza zugreifen können. Wir könnten also verwenden:

pizzas:live:{Id}

Beispiele:

Erstellen Sie eine Pizza

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);
}

Holen Sie sich eine Pizza von 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);
}

Aktualisieren Sie eine Pizza nach ID (Einfach ein GET und 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
}

Zu einer anderen "Liste" wechseln (vielleicht:wenn eine Pizza ihren Zustand ändert)

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);
}

Pizza löschen

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

Alle Live-Pizzen auflisten

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

Ich hoffe, das hilft.