【问题标题】:Unmarshalling BSON data using Gobson/Mgo使用 Gobson/Mgo 解组 BSON 数据
【发布时间】:2016-08-25 18:18:49
【问题描述】:

我收到了不同的 BSON 文档,这里有一个示例:

{ "group" : { "id": ObjectId("11a123456bc345d452d32c0b5"), "name": "SomeName" }, "count1": 6, "count2": 33, "totalCount": 39 }

我正在尝试使用 mgo/gobson 将这些数据解组到 map[string]interface{},但不断收到错误消息。解组代码是

var record map[string]interface{}

err := bson.Unmarshal(data, &record)

这导致错误提示文档已损坏。查看代码,我看到它预计字节数组的长度是前几个字节,所以我添加了类似于测试中的代码。

rec := make([]byte, len(data)+6)
binary.LittleEndian.PutUint32(rec, uint32(len(rec)))
copy(rec[4:], data)

这让我克服了损坏的文档错误,但现在我得到了

Unknown element kind (0x7B)

我不能轻松地将上述 BSON 文档解组为地图,我做错了什么? BSON 文档本身有问题吗?我不是 BSON 文档的创建者,但可以在必要时向他们提供反馈。

【问题讨论】:

  • 这听起来像是 BSON 文档的问题,而不是您的代码。文件来自哪里?
  • 文档由其他团队提供。我负责将数据提取并提取到我使用的系统中。
  • 我与另一个团队交谈,并被告知他们有一个用于查询 MongoDB 并将结果转储到文件中的脚本,这就是我想要的。
  • 你的 BSON 看起来像人类可读的 { "group" : { "id": ObjectId("11a123456bc345d452d32c0b5"), "name": "SomeName" }, "count1": 6, "count2": 33, "totalCount": 39 } 还是二进制形式?
  • 如果他们想给你 BSON,他们应该使用 mongodump 工具。我会与他们再次核对以确保。如果您能在此处概述他们的工作流程,那将非常有帮助。

标签: mongodb go bson


【解决方案1】:

我在上面尝试了您的代码,并设法让它“工作”。你得到的原因

Unknown element kind (0x7B)

是因为 BSON 规范中没有 0x7B 类型的元素。见这里http://bsonspec.org/spec.html。我得到的特定未知元素是文档中第一个花括号({)的字节值

{ "group" : { "id": ObjectId("11a123456bc345d452d32c0b5"), "name": "SomeName" }, "count1": 6, "count2": 33, "totalCount": 39 }

在稍微调整代码后,我能够让它在没有unknown kind 错误的情况下工作。

package main

import (
    "encoding/binary"
    "fmt"

    "gopkg.in/mgo.v2/bson"
)

func main() {
    bsonData := `{ "group" : { "id": ObjectId("11a123456bc345d452d32c0b5"), "name": "SomeName" }, "count1": 6, "count2": 33, "totalCount": 39 }`

    var record map[string]interface{}

    rec := make([]byte, len(bsonData)+6)
    binary.LittleEndian.PutUint32(rec, uint32(len(rec)))
    copy(rec[4:], bsonData)
    //Adding a new line to the front of the rec byte variable seems to do the trick
    r := []byte("\n")
    rec[4] = r[0]
    err := bson.Unmarshal(rec, &record)
    if err != nil {
        panic(err)
    }
    fmt.Println(record)
}

我还发现这个答案很有用https://stackoverflow.com/a/33129119/2627768

【讨论】:

  • 这似乎没有达到预期的效果。我最终将整个“bson 数据”作为映射中的键和 nil 值。
  • 您在上面用作 bsonData 的字符串不是有效的 BSON。它是 MongoDB 扩展 JSON。正如规范所解释的,BSON 是一种二进制格式。
猜你喜欢
  • 2018-04-16
  • 2015-12-30
  • 1970-01-01
  • 2019-05-09
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
相关资源
最近更新 更多