英文:
go-redis HGETALL protobuf message
问题
大家有没有尝试将Redis哈希存储为Proto Marshalled,并在结构中进行解组和检索?我在这方面遇到了问题。
我尝试以下步骤,但无法获得期望的结果:
- 定义一个接口
- 执行HGETALL并尝试将结果存储在上述接口中
- 转换为字节数组
- 将其解析为所需的结构体
注意:使用github.com/go-redis/redis/v8
中的redis.NewClusterClient
var res interface{}
res, err = redis.GoRedisInstance().Do(context.Background(), "HGETALL", key).Result()
if err != nil {
return nil, false, err
}
if response, ok := res.(string); ok {
value = []byte(response)
}
styleEntry, err := parseStyle(ctx, value)
func parseStyle(ctx context.Context, b []byte) (*style_fetch.CMSStyleRedisEntry, error) {
// 转换为产品Redis对象
productRedis := style_fetch.CMSStyleRedisEntry{}
err := proto.Unmarshal(b, &productRedis)
if err != nil {
return nil, err
}
return &productRedis, nil
}
在调试时,我看到redis.GoRedisInstance().Do(context.Background(), "HGETALL", key)
返回的是interface{}([]interface{})
,其中:
- key是
interface{}(string)
- value(Proto Marshalled)是
interface{}(string)
附上了快照,请参考这里。
但是,对于.Result()
,两者都返回了无法解析的接口类型。
对于HGET命令,它是有效的:
res, err = redis.GoRedisInstance().Do(context.Background(), "HGET", key, "style").Result()
style := style_fetch.Style{}
err := proto.Unmarshal(b, &style)
if err != nil {
return nil, err
}
productRedis := &style_fetch.CMSStyleRedisEntry{Style: &style}
return productRedis, nil
英文:
Hi has anyone tried storing redis hash as proto marshalled and unmarshall and retrieve in struct? I am facing issue in that.
Doing below but not able to get desired result
- defining an interface
- Execution HGETALL and trying to get result in above interface
- converting to byte array
- parsing it to required struct
Note: using redis.NewClusterClient
from github.com/go-redis/redis/v8
var res interface{}
res, err = redis.GoRedisInstance().Do(context.Background(), "HGETALL", key).Result()
if err != nil {
return nil, false, err
}
if response, ok := res.(string); ok {
value = []byte(response)
}
styleEntry, err := parseStyle(ctx, value)
func parseStyle(ctx context.Context, b []byte) (*style_fetch.CMSStyleRedisEntry, error) {
// convert to product redis object
productRedis := style_fetch.CMSStyleRedisEntry{}
err := proto.Unmarshal(b, &productRedis)
if err != nil {
return nil, err
}
return &productRedis, nil
}
While debugging
redis.GoRedisInstance().Do(context.Background(), "HGETALL", key)
I see interface{}([]interface{})
key - interface{}(string)
value(proto marshalled) - interface{}(string)
Attached snapshot
But .Result gives (unreadable could not resolve interface type) for both
It works for HGET though
res, err = redis.GoRedisInstance().Do(context.Background(), "HGET", key, "style").Result()
style := style_fetch.Style{}
err := proto.Unmarshal(b, &style)
if err != nil {
return nil, err
}
productRedis := &style_fetch.CMSStyleRedisEntry{Style: &style}
return productRedis, nil```
</details>
# 答案1
**得分**: 1
**已解决**
在这里,我们需要在单个字段级别上进行协议解组,而不是在整个结构上进行解组,因为我们在这里使用的是hset/hmset单个字段。
```go
unboxed, ok := res.(map[string]string)
if !ok {
fmt.Println("输出应该是一个指向map的指针")
}
//如果错误为nil,但值也为空/nil。在Redis中找不到数据,重新索引
if unboxed == nil || len(unboxed) <= 0 {
//异步重新索引调用
isCacheMiss = true
statsd.Instance().Incr("redis.keyNotPresentError", 1)
return nil, isCacheMiss, nil
}
redisEntry := &style_fetch.CMSStyleRedisEntry{}
for key, value := range unboxed {
if key == "style" {
style := &style_fetch.Style{}
proto.Unmarshal([]byte(value), style)
redisEntry.Style = style
}
//...其他键
}
英文:
Resolved
proto unmarshall required at invidual field level and not on whole struct as here we do hset/hmset individual fields
unboxed, ok := res.(map[string]string)
if !ok {
fmt.Println("Output should be a pointer of a map")
}
//If error is nil but value is also empty/nil. Data not found in redis, reindex
if unboxed == nil || len(unboxed) <= 0 {
//async reindexing call
isCacheMiss = true
statsd.Instance().Incr("redis.keyNotPresentError", 1)
return nil, isCacheMiss, nil
}
redisEntry := &style_fetch.CMSStyleRedisEntry{}
for key, value := range unboxed {
if key == "style" {
style := &style_fetch.Style{}
proto.Unmarshal([]byte(value), style)
redisEntry.Style = style
}
//...other keys
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论