【问题标题】:Read mongodump output with go and mgo使用 go 和 mgo 读取 mongodump 输出
【发布时间】:2014-06-13 04:13:46
【问题描述】:

我正在尝试读取由 mongodump 生成的集合转储。该文件有几 GB,所以我想逐步阅读它。

我可以用这样的方式读取第一个对象:

buf := make([]byte, 100000)
f, _ := os.Open(path)
f.Read(buf)

var m bson.M
bson.Unmarshal(buf, &m)

但是不知道buf消耗了多少,所以不知道下一个怎么看。

mgo 可以做到这一点吗?

【问题讨论】:

    标签: mongodb go mgo


    【解决方案1】:

    仅使用 mgo 的 bson.Unmarshal() 是不够的 - 该函数旨在获取代表单个文档的 []byte,并将其解组为一个值。

    您需要一个可以从转储文件中读取下一个完整文档的函数,然后您可以将结果传递给bson.Unmarshal()

    将此与encoding/jsonencoding/gob 进行比较,如果mgo.bson 有一个Reader 类型来使用来自io.Reader 的文档,那将会很方便。

    无论如何,从source for mongodump看来,转储文件只是一系列bson文档,没有文件页眉/页脚或明确的记录分隔符。

    BSONTool::processFile 显示 mongorestore 如何读取转储文件。他们的代码读取 4 个字节以确定文档的长度,然后使用该大小读取文档的其余部分。确认大小前缀是bson spec的一部分。

    这是一个playground example,它展示了如何在 Go 中完成此操作:读取长度字段,读取文档的其余部分,解组,重复。

    【讨论】:

    • 是的,对于这个用例,我们需要bson.NewDecoder(...)
    【解决方案2】:

    方法File.Read返回读取的字节数。

    File.Read

    Read 从文件中读取最多 len(b) 个字节。它返回读取的字节数和错误(如果有)。 EOF 由 err 设置为 io.EOF 的零计数发出信号。

    所以你可以通过简单地存储你读取的返回参数来获得读取的字节数:

    n, err := f.Read(buf)
    

    【讨论】:

      【解决方案3】:

      我设法用以下代码解决了这个问题:

      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):]
      }
      

      【讨论】:

        【解决方案4】:

        Niks Keets' answer 对我不起作用。不知何故,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:]
        }
        

        当然,您必须在缓冲区末尾处理截断的结构。就我而言,我可以将整个文件加载到内存中。

        【讨论】:

          猜你喜欢
          • 2017-12-30
          • 2017-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-03
          • 2014-06-07
          • 1970-01-01
          • 2015-03-15
          相关资源
          最近更新 更多