Mongodb 使用go和mgo读取mongodump输出
我正在尝试读取mongodump生成的集合转储。该文件只有几GB,因此我希望以增量方式读取它 我可以用如下方式阅读第一个对象:Mongodb 使用go和mgo读取mongodump输出,mongodb,go,mgo,Mongodb,Go,Mgo,我正在尝试读取mongodump生成的集合转储。该文件只有几GB,因此我希望以增量方式读取它 我可以用如下方式阅读第一个对象: buf := make([]byte, 100000) f, _ := os.Open(path) f.Read(buf) var m bson.M bson.Unmarshal(buf, &m) 但是我不知道buf消耗了多少,所以我不知道如何阅读下一个 mgo是否可以这样做?方法File.Read返回读取的字节数 Read从文件中最多读取len(b)个字
buf := make([]byte, 100000)
f, _ := os.Open(path)
f.Read(buf)
var m bson.M
bson.Unmarshal(buf, &m)
但是我不知道buf消耗了多少,所以我不知道如何阅读下一个
mgo是否可以这样做?方法
File.Read
返回读取的字节数
Read从文件中最多读取len(b)个字节。它返回读取的字节数和错误(如果有)。EOF由零计数发出信号,err设置为io.EOF
因此,只需存储读取的返回参数即可获得读取的字节数:
n, err := f.Read(buf)
仅使用mgo的
bson.Unmarshal()
是不够的——该函数设计用于获取表示单个文档的[]字节,并将其解组为一个值
您需要一个可以从转储文件中读取下一个完整文档的函数,然后可以将结果传递到bson.Unmarshal()
与encoding/json
或encoding/gob
相比,如果mgo.bson
有一个Reader
类型,该类型使用io.Reader
中的文档,这将非常方便
无论如何,从中可以看出,转储文件只是一系列bson文档,没有文件头/页脚或显式记录分隔符
显示mongorestore如何读取转储文件。他们的代码读取4个字节以确定文档的长度,然后使用该大小读取文档的其余部分。已确认大小前缀是的一部分
下面是一个演示如何在Go中执行此操作的示例:读取长度字段,读取文档的其余部分,解组,重复。我用以下代码解决了此问题:
for len(buf) > 0 {
var r bson.Raw
var m userObject
bson.Unmarshal(buf, &r)
r.Unmarshal(&m)
fmt.Println(m)
buf = buf[len(r.Data):]
}
不适合我。不知何故,len(r.Data)
始终是整个缓冲区的长度。所以我提出了另一个代码:
for len(buff) > 0 {
messageSize := binary.LittleEndian.Uint32(buff)
err = bson.Unmarshal(buff, &myObject)
if err != nil {
panic(err)
}
// Do your stuff
buff = buff[messageSize:]
}
当然,您必须在缓冲区的末尾处理截断的结构。就我而言,我可以将整个文件加载到内存中 是的,我们需要bson.NewDecoder(…)
理想情况下,对于这个用例。