将文档插入redis时出现问题。
我在Go中有一个数据结构:
type ArticleCovers struct {
ID int
Covers ArticleCovers
ArticleTypeID int
Address Address `gorm:"ForeignKey:AddressID"`
}
我想在Redis中添加这样的数据:
[ID:1 Cover:[http://chuabuuminh.vn/UserImages/2012/12/10/1/chinh_dien_jpg.jpg] ArticleTypeID:1 Address:map[Street: City:<nil> District:<nil> DistrictID:0 ID:0 Slug: Lat:0 Long:0 Ward:<nil> WardID:0 CityID:0]]
但是当我运行Redis.HMSet("test", structs.Map(ret))
时,它会返回错误:redis: can't marshal postgresql.ArticleCovers (consider implementing encoding.BinaryMarshaler)
。
谁能帮助我解决我的问题,非常感谢你!
答案 0 :(得分:1)
如错误消息所示,您需要为ArticleCovers
类型实施BinaryMarshaler
界面:
type ArticleCovers struct {
ID int
Covers ArticleCovers
ArticleTypeID int
Address Address `gorm:"ForeignKey:AddressID"`
}
func (ac ArticleCovers) MarshalBinary() ([]byte, error) {
return []byte(fmt.Sprintf("%v-%v", ac.ID, ac.ArticleTypeID)), nil
}
请注意,这只会添加ID
和ArticleTypeID
字段。我不知道是什么
ArticleCovers
和Address
类型看起来像,但通常你想打电话
相同的方法:
func (ac ArticleCovers) MarshalBinary() ([]byte, error) {
covers, err := ac.Covers.MarshalBinary()
if err != nil {
return nil, err
}
address, err := ac.Address.MarshalBinary()
if err != nil {
return nil, err
}
return []byte(fmt.Sprintf("%v-%v-%v-%v",
ac.ID, ac.ArticleTypeID, covers, address)
}
我不知道这种格式对您的数据是否有意义。你可能想用一个 定义的编码格式,如json。
您可能还希望实现BinaryUnmarshaler
接口。
这样做是为了练习; - )
答案 1 :(得分:0)
正如Carpetsmoker所说的JSON编码,这是怎么做的:
func (ac ArticleCovers) MarshalBinary() ([]byte, error) {
return json.Marshal(ac)
}
解码时你使用BinaryUnmarshaler
您可以在blog post
处查看更多示例答案 2 :(得分:0)
将任何类型的对象直接保存到Redis中时,它会尝试对其进行二进制哈希处理,因此您应实现MarshalBinary
使其起作用。想法是将值简单地保存为客户端内部处理的二进制格式或字符串格式。
话虽如此,保存对象的一种可能的简便方法是将它们保存为字符串格式,您仍然可以使用JSON
之类的不同编组技术来做到这一点。
func Save(obj interface{}) error {
Redis.HMSet("test", json.Marshal(obj))
}
尽管json是执行此操作的一种简便方法,但是通过使用二进制而不是基于文本的编码,可以提高性能。 gop是可以对对象进行编码和解码的软件包。 protocol buffers现在也被广泛使用,尤其是在我们使用不同语言和集成的情况下。
这是一个简单的example,其中包含gop
和MarshalBinary