Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 使用mongo驱动程序自定义BSON封送和解封送_Mongodb_Go_Protocol Buffers_Marshalling_Bson - Fatal编程技术网

Mongodb 使用mongo驱动程序自定义BSON封送和解封送

Mongodb 使用mongo驱动程序自定义BSON封送和解封送,mongodb,go,protocol-buffers,marshalling,bson,Mongodb,Go,Protocol Buffers,Marshalling,Bson,我有一个如下所示的结构字段。我还将同一结构的原始protobuf存储在db中。现在,每次获取或保存数据到mongo。当我想保存到数据库时,我必须从proto更新ReallyBigRaw,当获取时,我必须将ReallyBigRaw解组到ReallyBigObj以给出响应。是否有一种方法可以实现一些接口或提供一些回调函数,以便mongo驱动程序在保存或从DB获取数据之前自动执行此操作 另外,我使用的是官方的golang mongo驱动程序,而不是mgo,我已经在mgogolang库中阅读了一些答案

我有一个如下所示的结构字段。我还将同一结构的原始protobuf存储在db中。现在,每次获取或保存数据到mongo。当我想保存到数据库时,我必须从proto更新
ReallyBigRaw
,当获取时,我必须将
ReallyBigRaw
解组到
ReallyBigObj
以给出响应。是否有一种方法可以实现一些接口或提供一些回调函数,以便mongo驱动程序在保存或从DB获取数据之前自动执行此操作

另外,我使用的是官方的golang mongo驱动程序,而不是
mgo
,我已经在
mgo
golang库中阅读了一些答案

导入(
“github.com/golang/protobuf/jsonpb”
“go.mongodb.org/mongo-driver/bson”
“go.mongodb.org/mongo-driver/bson/primitive”
原型“github.com/dinesh/api/go”
)
类型ReallyBig结构{
ID字符串`bson:“\u ID,省略为空”`
DraftID字符串`bson:“draft_id,省略为空”`
//封送ReallyBigObj proto以映射数据库中存储的[string]接口{}
ReallyBigRaw映射[string]接口{}`bson:“原始,省略空”`
ReallyBigObj*proto.ReallyBig`bson:“`
CreatedAt primitive.DateTime`bson:“已创建,省略为空”`
UpdatedAt primitive.DateTime`bson:“已更新,省略为空”`
}
func(r*ReallyBig)GetProto()(*proto.ReallyBig,错误){
如果r.ReallyBigObj!=nil{
返回r.ReallyBigObj,无
}
Obj,err:=getProto(r.ReallyBigRaw)
如果错误!=零{
返回零,错误
}
r、 ReallyBigObj=Obj
返回r.ReallyBigObj,无
}
func getRaw(r*proto.ReallyBig)(映射[string]接口{},错误){
m:=jsonpb.Marshaler{}
b:=bytes.NewBuffer([]字节{})
//将proto封送为json格式
err:=m.Marshal(b,r)
如果错误!=零{
返回零,错误
}
var原始映射[string]接口{}
//将原始数据解组到接口
err=json.Unmarshal(b.Bytes(),&raw)
如果错误!=零{
返回零,错误
}
归零
}
func getProto(原始映射[string]接口{})(*proto.ReallyBig,错误){
b、 err:=json.Marshal(原始)
如果错误!=零{
返回零,错误
}
u:=jsonpb.Unmarshaler{}
变量reallyBigProto proto.ReallyBig
err=u.Unmarshal(bytes.NewReader(b)和recipeProto)
如果错误!=零{
返回零,错误
}
return&reallyBigProto,无
}

我实现了
Marshaler
Unmarshaler
接口。由于mongo驱动程序调用
MarshalBSON
UnmarshalBSON
,如果类型实现了
Marshaler
Unmarshaler
,那么我们也会在无限循环中结束。为了避免这种情况,我们创建了
类型的别名
Golang
中的别名只继承字段而不是方法,因此我们最终调用normal
bson.Marshal
bson.Unmarshal

func(r*ReallyBig)marshallbson()([]字节,错误){
输入ReallyBigAlias ReallyBig
reallyBigRaw,err:=getRaw(r.ReallyBigObj)
如果错误!=零{
返回零,错误
}
r、 ReallyBigRaw=ReallyBigRaw
返回bson.Marshal((*ReallyBigAlias)(r))
}
func(r*ReallyBig)解组SALBSON(数据[]字节)错误{
输入ReallyBigAlias ReallyBig
错误:=bson.Unmarshal(数据,(*ReallyBigAlias)(r))
如果错误!=零{
返回错误
}
reallyBigProto,err:=getProto(r.ReallyBigRaw)
如果错误!=零{
返回错误
}
r、 ReallyBigObj=reallyBigProto
归零
}

bson.Marshaler
bson.Unmarshaler
也与官方司机一起工作。另一种方法是使用编码器和解码器,例如,请参阅Thank a ton。该示例讨论处理类型。但是在我的例子中,我只需要用当前的proto状态更新raw字段,然后让mongo处理到DB的封送,当从DB解封时,只需要从该raw填充proto。举个例子会很有帮助。@icza我能够实现封送器和解封送器