我需要的是相当于Document.parse()的golang方法,允许我直接从json创建bson? 我不想创建中间的Go结构来进行编组。
gopkg.in/mgo.v2/bson
包有一个名为UnmarshalJSON
的函数,它正好可以满足您的需求。
data
参数应该将您的JSON字符串作为[]byte
值保存。
func UnmarshalJSON(data []byte, value interface{}) error
UnmarshalJSON将一个可能包含 BSON 扩展 JSON 规范中定义的非标准语法的 JSON 值进行反序列化。
示例:
var bdoc interface{}
err = bson.UnmarshalJSON([]byte(`{"id": 1,"name": "A green door","price": 12.50,"tags": ["home", "green"]}`),&bdoc)
if err != nil {
panic(err)
}
err = c.Insert(&bdoc)
if err != nil {
panic(err)
}
mongo-go-driver
有一个名为bson.UnmarshalExtJSON
的函数可以完成这项工作。
以下是示例:
var doc interface{}
err := bson.UnmarshalExtJSON([]byte(`{"foo":"bar"}`), true, &doc)
if err != nil {
// handle error
}
doc
将使用 ExtendedJson
格式,这可能会重新构造输入以包括 mongo bson 类型系统。 - dustinevan现在没有支持的库(例如mongo-go-driver)可以直接完成此操作。您需要根据bson规范编写自己的转换器。
编辑:这是一个已经在生产环境中使用了几TB的转换器。 https://github.com/dustinevan/mongo/blob/main/bsoncv/bsoncv.go
import (
"fmt"
"github.com/sindbach/json-to-bson-go/convert"
"github.com/sindbach/json-to-bson-go/options"
)
func main() {
doc := `{"foo": "buildfest", "bar": {"$numberDecimal":"2021"} }`
opt := options.NewOptions()
result, _ := convert.Convert([]byte(doc), opt)
fmt.Println(result)
}
package main
import "go.mongodb.org/mongo-driver/bson/primitive"
type Example struct {
Foo string `bson:"foo"`
Bar primitive.Decimal128 `bson:"bar"`
}
这个模块与官方MongoDB Go驱动程序兼容,正如您所看到的,它支持扩展JSON格式。
您还可以访问https://json-to-bson-map.netlify.app来尝试该模块。您可以粘贴一个JSON文档,然后查看Go BSON结构作为输出。
go.mongodb.org/mongo-driver/bson/bsonrw
:
func JsonToBson(message []byte) ([]byte, error) {
reader, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(message), true)
if err != nil {
return []byte{}, err
}
buf := &bytes.Buffer{}
writer, _ := bsonrw.NewBSONValueWriter(buf)
err = bsonrw.Copier{}.CopyDocument(writer, reader)
if err != nil {
return []byte{}, err
}
marshaled := buf.Bytes()
return marshaled, nil
}