如何在Redis Hashes上处理强类型?

时间:2016-05-22 09:33:05

标签: c# redis json.net stackexchange.redis

我的客户端向服务器发送一个json( JObject ),我有一个自定义方法,将值展平为一个键值对。

假设这是我的json

{
   Prop1: 12,
   Prop2: "Str",
   Prop3:{
      Prop4: 222.4
   }
}

创建了一个扁平数据字典,如下所示:

"Prop1": 12
"Prop2": "Str"
"Prop3.Prop4": 222.4

现在,我正在使用 Redis StackExchange.Redis 客户端)来保存这些数据。

我生成一个密钥(例如obj:123456)并将字典的键值添加为哈希条目。

数据保存在 Redis 上,但我的问题是我需要在从 Redis 检索数据时区分类型。

我注意到IsInteger标志,并想尝试将其用作开头。 我创建了一个HashEntry,其中包含一个整数值(IsInteger为真),然后是HashSetted数据。 当我使用HashGet获取数据时,我注意到IsInteger标志为false。

IsIntegerHashSet之间是否有HashGet标记丢失的原因?

Redis 上处理类型(string \ int \ double \ date)有什么简单的方法吗?我可以想到一个自定义实现,但我想去那里。

编辑 - 这是一个代码示例:

Dictionary<string, object> objs = new Dictionary<string, object>
{
    {"Prop1", 12},
    {"Prop2", "Str"},
    {"Prop3.Prop4", 222.4},
};

var redisConnection = ConnectionMultiplexer.Connect(ConfigurationOptions.Parse("localhost:6379,name=SafeRedisConnection,connectTimeout=100000,syncTimeout=100000,abortConnect=false,defaultDatabase=5"));

// just a test
var hashEntries = objs.Where(kvp => kvp.Value is int).Select(kvp => new HashEntry(kvp.Key, (int)kvp.Value));
var hashEntries1 = objs.Where(kvp => kvp.Value is string).Select(kvp => new HashEntry(kvp.Key, (string)kvp.Value));
var hashEntries2 = objs.Where(kvp => kvp.Value is double).Select(kvp => new HashEntry(kvp.Key, (double)kvp.Value));

var arr = hashEntries.Union(hashEntries1).Union(hashEntries2).ToArray();
redisConnection.GetDatabase().HashSet("obj:123456", arr);

var keys = redisConnection.GetDatabase().HashKeys("obj:123456");
var dic = keys.ToDictionary(k => k, k => redisConnection.GetDatabase().HashGet("obj:123456", k));

1 个答案:

答案 0 :(得分:1)

您应该使用自己的Redis密钥命名约定。请记住,在Redis中,所有简单值都是 strings (好吧,字节数组......但是 StackExchange.Redis 有一个隐式运算符来转换RedisValue进入string)。

例如,当您在某些Redis哈希上添加时,密钥可能是<propertyName>:<type>,这样您就可以再次将键值转换为CLR类型...... < / p>

另一种方法可能是存储哈希值以及每个哈希值的另一个哈希值来存储密钥的数据类型:

var hashEntries = objs.Where(kvp => kvp.Value is int)
                      .Select
                      (
                          kvp => new HashEntry
                          (
                              kvp.Key, 
                              kvp.Value.GetType().AssemblyQualifiedName
                          )
                      );

每当您获得部分或全部哈希条目时,您也可以获得其元数据对应项以检查每种值类型。

顺便说一句,我相信您应该考虑将JSON序列化对象注入全局/分区哈希,或者使用简单的键串密钥作为全局键空间的一部分,您将避免这些问题。

如果我需要执行某些操作(例如通过某些属性或其他情况索引数据),我会使用哈希来存储单个属性...但如果您只是存储完整对象,请考虑我的目的。