Mongodb 使用go和mgo读取mongodump输出

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)个字

我正在尝试读取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)个字节。它返回读取的字节数和错误(如果有)。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(…)
理想情况下,对于这个用例。