2015-08-12 11 views
10

Ho usato StackExchange.Redis per la cache di # cis.Come memorizzare l'elemento dell'elenco nella cache Redis

cache.StringSet("Key1", CustomerObject); 

ma voglio memorizzare i dati come

cache.StringSet("Key1", ListOfCustomer); 

in modo che una chiave ha memorizzato tutte Elenco clienti ed è facile da di ricerca, di gruppo, filtrare i dati dei clienti anche all'interno di tale lista

Le risposte sono i benvenuti con ServiceStack.Redis o StackExchange.Redis

risposta

5

È possibile utilizzare ServiceStack.Redis alto livello IRedisTypedClient Typed API per la gestione di tipi POCO ricchi.

Prima ottenere un client Redis digitato per i clienti con:

var redisCustomers = redis.As<Customer>(); 

che risolverà un alto livello di API digitato per la gestione dei clienti POCO di che poi ti permette di persistere un singolo cliente con:

redisCustomers.SetEntry("Customer1", CustomerObject); 

o un elenco di clienti con:

redisCustomers.Lists["Customers"].AddRange(ListOfCustomer); 
+5

Prestare attenzione a ServiceStack.Redis [limiti per l'utilizzo gratuito] (https://servicestack.net/download#free-quotas) – thepirat000

+0

@ thepirat000 come utilizzare l'elenco utilizzando 'ServiceStack.Redis'? – Neo

+1

Dipende da come si desidera accedere all'elenco. Recupererai sempre l'intero elenco da redis o vuoi gestire gli elementi singolarmente? – thepirat000

23

se si utilizza Stackechange.Redis, è possibile utilizzare i metodi Elenco sulla sua API. Ecco un'implementazione ingenua di IList che utilizza un elenco redis per archiviare gli articoli.

Speriamo che può aiutare a capire alcuni dei metodi lista API:

public class RedisList<T> : IList<T> 
{ 
    private static ConnectionMultiplexer _cnn; 
    private string key; 
    public RedisList(string key) 
    { 
     this.key = key; 
     _cnn = ConnectionMultiplexer.Connect("localhost"); 
    } 
    private IDatabase GetRedisDb() 
    { 
     return _cnn.GetDatabase(); 
    } 
    private string Serialize(object obj) 
    { 
     return JsonConvert.SerializeObject(obj); 
    } 
    private T Deserialize<T>(string serialized) 
    { 
     return JsonConvert.DeserializeObject<T>(serialized); 
    } 
    public void Insert(int index, T item) 
    { 
     var db = GetRedisDb(); 
     var before = db.ListGetByIndex(key, index); 
     db.ListInsertBefore(key, before, Serialize(item)); 
    } 
    public void RemoveAt(int index) 
    { 
     var db = GetRedisDb(); 
     var value = db.ListGetByIndex(key, index); 
     if (!value.IsNull) 
     { 
      db.ListRemove(key, value); 
     } 
    } 
    public T this[int index] 
    { 
     get 
     { 
      var value = GetRedisDb().ListGetByIndex(key, index); 
      return Deserialize<T>(value.ToString()); 
     } 
     set 
     { 
      Insert(index, value); 
     } 
    } 
    public void Add(T item) 
    { 
     GetRedisDb().ListRightPush(key, Serialize(item)); 
    } 
    public void Clear() 
    { 
     GetRedisDb().KeyDelete(key); 
    } 
    public bool Contains(T item) 
    { 
     for (int i = 0; i < Count; i++) 
     { 
      if (GetRedisDb().ListGetByIndex(key, i).ToString().Equals(Serialize(item))) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
    public void CopyTo(T[] array, int arrayIndex) 
    { 
     GetRedisDb().ListRange(key).CopyTo(array, arrayIndex); 
    } 
    public int IndexOf(T item) 
    { 
     for (int i = 0; i < Count; i++) 
     { 
      if (GetRedisDb().ListGetByIndex(key, i).ToString().Equals(Serialize(item))) 
      { 
       return i; 
      } 
     } 
     return -1; 
    } 
    public int Count 
    { 
     get { return (int)GetRedisDb().ListLength(key); } 
    } 
    public bool IsReadOnly 
    { 
     get { return false; } 
    } 
    public bool Remove(T item) 
    { 
     return GetRedisDb().ListRemove(key, Serialize(item)) > 0; 
    } 
    public IEnumerator<T> GetEnumerator() 
    { 
     for (int i = 0; i < this.Count; i++) 
     { 
      yield return Deserialize<T>(GetRedisDb().ListGetByIndex(key, i).ToString()); 
     } 
    } 
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     for (int i = 0; i < this.Count; i++) 
     { 
      yield return Deserialize<T>(GetRedisDb().ListGetByIndex(key, i).ToString()); 
     } 
    } 
} 

Nota l'uso del Newtonsoft.Json per la serializzazione. Avrete bisogno dei seguenti-get nu pacchetti:

Install-Package Newtonsoft.Json 
Install-Package StackExchange.Redis 

Dopo aver letto la tua domanda e commenti, dal momento che si desidera accedere agli elementi di chiave, penso che stai cercando Redis Hashes, quali sono le mappe composte da campi associati con valori.

Quindi è possibile avere una chiave Redis per un hash contenente tutti i clienti, ognuno dei quali è un valore associato a un campo. Puoi scegliere CustomerId come campo, quindi puoi ottenere un cliente tramite il suo id in O (1).

Penso che l'implementazione di IDictionary sia un buon modo per vederlo funzionare. Quindi una classe RedisDictionary simile al RedisList ma utilizzando una Redis Hash potrebbe essere:

public class RedisDictionary<TKey, TValue> : IDictionary<TKey, TValue> 
{ 
    private static ConnectionMultiplexer _cnn; 
    private string _redisKey; 
    public RedisDictionary(string redisKey) 
    { 
     _redisKey = redisKey; 
     _cnn = ConnectionMultiplexer.Connect("localhost"); 
    } 
    private IDatabase GetRedisDb() 
    { 
     return _cnn.GetDatabase(); 
    } 
    private string Serialize(object obj) 
    { 
     return JsonConvert.SerializeObject(obj); 
    } 
    private T Deserialize<T>(string serialized) 
    { 
     return JsonConvert.DeserializeObject<T>(serialized); 
    } 
    public void Add(TKey key, TValue value) 
    { 
     GetRedisDb().HashSet(_redisKey, Serialize(key), Serialize(value)); 
    } 
    public bool ContainsKey(TKey key) 
    { 
     return GetRedisDb().HashExists(_redisKey, Serialize(key)); 
    } 
    public bool Remove(TKey key) 
    { 
     return GetRedisDb().HashDelete(_redisKey, Serialize(key)); 
    } 
    public bool TryGetValue(TKey key, out TValue value) 
    { 
     var redisValue = GetRedisDb().HashGet(_redisKey, Serialize(key)); 
     if (redisValue.IsNull) 
     { 
      value = default(TValue); 
      return false; 
     } 
     value = Deserialize<TValue>(redisValue.ToString()); 
     return true; 
    } 
    public ICollection<TValue> Values 
    { 
     get { return new Collection<TValue>(GetRedisDb().HashValues(_redisKey).Select(h => Deserialize<TValue>(h.ToString())).ToList()); } 
    } 
    public ICollection<TKey> Keys 
    { 
     get { return new Collection<TKey>(GetRedisDb().HashKeys(_redisKey).Select(h => Deserialize<TKey>(h.ToString())).ToList()); } 
    } 
    public TValue this[TKey key] 
    { 
     get 
     { 
      var redisValue = GetRedisDb().HashGet(_redisKey, Serialize(key)); 
      return redisValue.IsNull ? default(TValue) : Deserialize<TValue>(redisValue.ToString()); 
     } 
     set 
     { 
      Add(key, value); 
     } 
    } 
    public void Add(KeyValuePair<TKey, TValue> item) 
    { 
     Add(item.Key, item.Value); 
    } 
    public void Clear() 
    { 
     GetRedisDb().KeyDelete(_redisKey); 
    } 
    public bool Contains(KeyValuePair<TKey, TValue> item) 
    { 
     return GetRedisDb().HashExists(_redisKey, Serialize(item.Key)); 
    } 
    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) 
    { 
     GetRedisDb().HashGetAll(_redisKey).CopyTo(array, arrayIndex); 
    } 
    public int Count 
    { 
     get { return (int)GetRedisDb().HashLength(_redisKey); } 
    } 
    public bool IsReadOnly 
    { 
     get { return false; } 
    } 
    public bool Remove(KeyValuePair<TKey, TValue> item) 
    { 
     return Remove(item.Key); 
    } 
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() 
    { 
     var db = GetRedisDb(); 
     foreach (var hashKey in db.HashKeys(_redisKey)) 
     { 
      var redisValue = db.HashGet(_redisKey, hashKey); 
      yield return new KeyValuePair<TKey, TValue>(Deserialize<TKey>(hashKey.ToString()), Deserialize<TValue>(redisValue.ToString())); 
     } 
    } 
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     yield return GetEnumerator(); 
    } 
    public void AddMultiple(IEnumerable<KeyValuePair<TKey, TValue>> items) 
    { 
     GetRedisDb() 
      .HashSet(_redisKey, items.Select(i => new HashEntry(Serialize(i.Key), Serialize(i.Value))).ToArray()); 
    } 
} 

Ed ecco alcuni esempi per usarlo:

// Insert customers to the cache    
var customers = new RedisDictionary<int, Customer>("customers"); 
customers.Add(100, new Customer() { Id = 100, Name = "John" }); 
customers.Add(200, new Customer() { Id = 200, Name = "Peter" }); 

// Or if you have a list of customers retrieved from DB: 
IList<Customer> customerListFromDb; 
customers.AddMultiple(customerListFromDb.ToDictionary(k => k.Id)); 

// Query a customer by its id 
var customers = new RedisDictionary<int, Customer>("customers"); 
Customer customer100 = customers[100]; 

Update (Ottobre 2015)

A una migliore implementazione di queste raccolte può essere trovata nella libreria CachingFramework.Redis.

Here è il codice.

+0

grazie mille a qualsiasi esempio di esempio per lo stesso con i valori della lista clienti con una chiave? – Neo

+0

Grazie molto come il mio requisito è memorizzato i valori dei clienti in un elenco clienti e sono in grado di ottenere valori dalla lista passando il nome del cliente anche – Neo

+0

impossibile per ottenere tutti gli elementi del cliente utilizzando 'customers.AddMultiple (customerListFromDb.ToDictionary (k => k .ID)); ' – Neo

Problemi correlati