如何在Redis缓存中存储列表元素
How to store list element in Redis cache
我已经使用 StackExchange.Redis
用于 c# redis 缓存。
cache.StringSet("Key1", CustomerObject);
但我想像
一样存储数据
cache.StringSet("Key1", ListOfCustomer);
so that one key has all Customer List stored and it is easy to
search,group,filter customer Data also inside that List
欢迎使用 ServiceStack.Redis
或 StackExchange.Redis
回答
您可以使用 ServiceStack.Redis high-level IRedisTypedClient Typed API 来管理丰富的 POCO 类型。
首先为以下客户获取类型化的 Redis 客户端:
var redisCustomers = redis.As<Customer>();
这将解析用于管理客户 POCO 的高级类型 API,然后您可以通过以下方式保留单个客户:
redisCustomers.SetEntry("Customer1", CustomerObject);
或客户列表:
redisCustomers.Lists["Customers"].AddRange(ListOfCustomer);
如果你使用Stackechange.Redis,你可以在其API上使用List方法。
这是 IList 的简单实现,它使用 redis 列表来存储项目。
希望能帮助大家理解列表中的一些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());
}
}
}
注意使用 Newtonsoft.Json 进行序列化。
您将需要以下 nu-get 包:
Install-Package Newtonsoft.Json
Install-Package StackExchange.Redis
阅读您的问题和评论后,由于您想按键访问元素,我认为您正在寻找 Redis Hashes,它们是由与值关联的字段组成的映射。
因此,您可以拥有一个包含所有客户的哈希值的 Redis 键,每个客户都是与字段相关联的值。您可以选择 CustomerId 作为字段,这样您就可以在 O(1) 中通过其 ID 获取客户。
我认为实现 IDictionary 是查看其工作的好方法。
因此,类似于 RedisList 但使用 Redis 哈希的 RedisDictionary class 可能是:
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());
}
}
下面是一些使用它的例子:
// 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];
更新(2015 年 10 月)
可以在 CachingFramework.Redis 库中找到这些集合的更好实现。
Here是代码。
StackExchange.Redis 已经预定义函数来处理列表和值集。
获取 IDatabase 对象:
字符串缓存连接 = Utils.Sections.Storage.RedisCache.ConnectionString;
IDatabase 缓存 = ConnectionMultiplexer.Connect(cacheConnection).GetDatabase();
列表方法:
cache.ListLeftPushAsync(key, values) -> 推送元素列表之一
cache.ListRangeAsync(key, startIndex, endIndex) -> 获取值列表
cache.KeyExpire(键,时间跨度)
更多方法请打包StackExchange.Redis。您不需要包含任何额外的 nuget 包。
我已经使用 StackExchange.Redis
用于 c# redis 缓存。
cache.StringSet("Key1", CustomerObject);
但我想像
一样存储数据cache.StringSet("Key1", ListOfCustomer);
so that one key has all Customer List stored and it is easy to search,group,filter customer Data also inside that List
欢迎使用 ServiceStack.Redis
或 StackExchange.Redis
您可以使用 ServiceStack.Redis high-level IRedisTypedClient Typed API 来管理丰富的 POCO 类型。
首先为以下客户获取类型化的 Redis 客户端:
var redisCustomers = redis.As<Customer>();
这将解析用于管理客户 POCO 的高级类型 API,然后您可以通过以下方式保留单个客户:
redisCustomers.SetEntry("Customer1", CustomerObject);
或客户列表:
redisCustomers.Lists["Customers"].AddRange(ListOfCustomer);
如果你使用Stackechange.Redis,你可以在其API上使用List方法。 这是 IList 的简单实现,它使用 redis 列表来存储项目。
希望能帮助大家理解列表中的一些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());
}
}
}
注意使用 Newtonsoft.Json 进行序列化。 您将需要以下 nu-get 包:
Install-Package Newtonsoft.Json
Install-Package StackExchange.Redis
阅读您的问题和评论后,由于您想按键访问元素,我认为您正在寻找 Redis Hashes,它们是由与值关联的字段组成的映射。
因此,您可以拥有一个包含所有客户的哈希值的 Redis 键,每个客户都是与字段相关联的值。您可以选择 CustomerId 作为字段,这样您就可以在 O(1) 中通过其 ID 获取客户。
我认为实现 IDictionary 是查看其工作的好方法。 因此,类似于 RedisList 但使用 Redis 哈希的 RedisDictionary class 可能是:
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());
}
}
下面是一些使用它的例子:
// 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];
更新(2015 年 10 月)
可以在 CachingFramework.Redis 库中找到这些集合的更好实现。
Here是代码。
StackExchange.Redis 已经预定义函数来处理列表和值集。
获取 IDatabase 对象:
字符串缓存连接 = Utils.Sections.Storage.RedisCache.ConnectionString;
IDatabase 缓存 = ConnectionMultiplexer.Connect(cacheConnection).GetDatabase();
列表方法:
cache.ListLeftPushAsync(key, values) -> 推送元素列表之一
cache.ListRangeAsync(key, startIndex, endIndex) -> 获取值列表
cache.KeyExpire(键,时间跨度)
更多方法请打包StackExchange.Redis。您不需要包含任何额外的 nuget 包。