如何将JSON字符串转换为BSON文档以写入MongoDB?

18
我需要的是相当于Document.parse()的golang方法,允许我直接从json创建bson? 我不想创建中间的Go结构来进行编组。

你可以选择使用一些中间结构来进行编组/解组(高级接口),或者直接使用bson,或者像bson.M、bson.D这样的低级别。请参考https://dev59.com/j4Lba4cB1Zd3GeqPkNhO - lofcek
5个回答

20

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

第二个参数的值应该是什么类型,文档好像没有详细说明?根据我对Go的理解,interface{}相当于C语言中的void *或Java中的Object?如果有一个unmarshalJSON的指针示例就更好了。 - Ganesh
void和interface{}之间有很大的区别。当变量为void时,无法找到变量的类型。而interface{}知道类型。 - lofcek

9

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

1

1
我不想创建中间的 Go 结构体进行编组。
如果你确实需要创建一个中间的 Go BSON 结构体,你可以使用一个转换模块,例如 github.com/sindbach/json-to-bson-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结构作为输出。


1
一个简单的转换器,使用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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接