Как преобразовать документ BSON в интерфейс map [string] {} - PullRequest
0 голосов
/ 10 января 2019

Я пытался декодировать данные курсора в интерфейс map [string] {}, я пробовал это напрямую, но он не работает вообще, поэтому я решил, что мне нужно преобразовать их в документ BSON и затем преобразуйте его в map [string] interface {} и, наконец, в строку JSON. Я попробовал следующий код:

...
for cursor.Next(context.Background()) {
    err = cursor.Decode(&itemBson)
    ...
    b, err := bson.Marshal(itemBson)
    ...
    err = bson.Unmarshal(b, &itemMap)
    ...
}
...

Но документ bson имеет следующее значение:

map [_id: ObjectID ("5c2d0809a49bad7d547ec028") приложения: bson.Array [bson.Document {bson.Element {"enabled": true}}] userName: coto userUUID: df2d ea92-c189-53b3-aafe-485d0be23bee]

А карта разбирается как JSON:

{ "_ идентификатор": "5c2d0809a49bad7d547ec028", "приложения": [{}], "имя_пользователя": "Кото", "userUUID": "df2dea92-c189-53b3-aafe-485d0be23bee"}

Как вы можете видеть, ключ "application" в JSON пуст, но он действительно имеет содержание в документе BSON. Я не знаю, почему исчезают данные.

Как я могу решить эту ошибку? Спасибо.

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Решено:

Я решил эту ошибку, используя следующий код:

var jsonDocuments []map[string]interface{}
var byteDocuments []byte

var bsonDocument bson.D
var jsonDocument map[string]interface{}
var temporaryBytes []byte

for cursor.Next(context.Background()) {
    err = cursor.Decode(&bsonDocument)

    if err != nil {
        report.Report{Error: err, Trace: report.Trace()}.Send()
        requestContext.StatusCode(500)
        return `500 Internal server error`
    }

    temporaryBytes, err = bson.MarshalExtJSON(bsonDocument, true, true)

    if err != nil {
        report.Report{Error: err, Trace: report.Trace()}.Send()
        requestContext.StatusCode(500)
        return `500 Internal server error`
    }

    err = json.Unmarshal(temporaryBytes, &jsonDocument)

    if err != nil {
        report.Report{Error: err, Trace: report.Trace()}.Send()
        requestContext.StatusCode(500)
        return `500 Internal server error`
    }

    jsonDocuments = append(jsonDocuments, jsonDocument)
}
0 голосов
/ 11 января 2019

Официальный mongo-go-драйвер bson.M - это pimitive.M, тип map[string]interface{}. Не видя ваших объявленных переменных, трудно сказать, что пошло не так. Вот рабочий пример использования официального драйвера mongo-go.

func TestUnmarshal(t *testing.T) {
    uri := "mongodb://localhost/stackoverflow?replicaSet=replset"
    ctx := context.Background()
    client, err := mongo.Connect(ctx, uri)
    if err != nil {
        t.Fatal(err)
    }
    c := client.Database("stackoverflow").Collection("acoll")
    list := []bson.M{bson.M{"enabled": true}}
    id := primitive.NewObjectID()
    c.InsertOne(ctx, bson.M{"_id": id, "applications": list, "userName": "my name"})
    var itemBson bson.M
    var itemMap map[string]interface{}
    cur, _ := c.Find(ctx, bson.M{})
    for cur.Next(ctx) {
        cur.Decode(&itemBson)
        t.Log(itemBson)
        b, _ := bson.Marshal(itemBson)
        bson.Unmarshal(b, &itemMap)
        t.Log(itemMap)
    }
}

выход go test

    unmarshal_test.go:28: map[_id:ObjectID("5c380ae501d48897a1ac27c6") applications:[map[enabled:true]] userName:my name]
    unmarshal_test.go:31: map[userName:my name _id:ObjectID("5c380ae501d48897a1ac27c6") applications:[map[enabled:true]]]
...