sql >> Databasteknik >  >> NoSQL >> Redis

Uppdaterar Service Stack Redis List

Undvik listor:

Tyvärr är Redis-listor inte riktigt ett bra val i den här situationen. Jag hade samma problem när jag började använda Redis, de verkar vara det självklara valet;). Redis-listor är användbara om du använder dem som en skrivskyddad uppsättning, eller om du bara vill poppa och trycka, men inte för att ändra ett objekt i mitten av listan.

Du kan "uppdatera" objekt i en Redis-lista om du känner till objektets index, men det kräver att du ta bort och infoga igen , och det måste vara genom index, vilket är fruktansvärt ineffektivt. Det gör det genom att upprepa samlingen, eftersom det inte finns något inhemskt sätt att göra det på, och det här är inte en bra idé. Detta är ett utdrag av IndexOf metod för 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;
}

Så för att komplettera din kod, skulle det vara:

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

Men det här är inget trevligt sätt att hantera det som jag har sagt. Den kommer att hämta listan över de andra pizzaobjekten och sedan iterera över dem tills den matchar indexet. Och två operationer att uppdatera! :( Bäst att undvika listor i den här situationen.

Lösning:

När du försöker komma åt pizzan med dess ID kan du skapa en unik pizzanyckel för varje objekt, vilket gör att du kan komma åt pizzan direkt. Så vi kan använda:

pizzas:live:{Id}

Exempel:

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

Få en pizza efter 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);
}

Uppdatera en pizza efter ID (Helt enkelt en GET och 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
}

Flytta till en annan "lista" (kanske:när en pizza ändrar status)

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

Ta bort en pizza

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

Lista alla levande pizzor

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

Jag hoppas att detta hjälper.




  1. 5 sätt att få timmen från en dejt i MongoDB

  2. Ändra Redis-port i Docker Compose fungerar inte

  3. Oväntad mongo exit-kod 100. Startar om

  4. Vad är grundläggande MongoDB-kommandon och hur man använder dem?