dozrhldy285751 2016-08-24 18:27
浏览 227

使用Gobson / Mgo解组BSON数据

I am receiving different BSON documents, an example seen here:

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

I am trying to use mgo/gobson to unmarshal this data into a map[string]interface{}, but keep getting an error. The unmarshalling code is

var record map[string]interface{}

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

This resulted in a error saying the document was corrupted. Looking into the code I saw that it expected the length of the byte array to be the first few bytes so I added code similar to what is found in the tests.

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

This got me past the corrupt document error, but now I am getting

Unknown element kind (0x7B)

What am I doing wrong that I can't easily unmarshal the above BSON document into a map? Is there a problem with the BSON document itself? I am not the creator of the BSON document, but am able to provide feedback to them if necessary.

  • 写回答

1条回答 默认 最新

  • dongmiao520892 2016-08-25 10:10
    关注

    I tried out your code above and I managed to get it to "work". The reason you are getting

    Unknown element kind (0x7B)
    

    is because there is no element of kind 0x7B in the BSON specification. See here http://bsonspec.org/spec.html. The particular unknow element I was getting was the byte value for the first curly bracket({) in your document

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

    after tweaking the code a bit I was able to get it working with out the unknown kind error.

    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("
    ")
        rec[4] = r[0]
        err := bson.Unmarshal(rec, &record)
        if err != nil {
            panic(err)
        }
        fmt.Println(record)
    }
    

    I also found this answer to be of great use https://stackoverflow.com/a/33129119/2627768

    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘