Как преобразовать документ BSON в интерфейс map[string] {}
Я пытался декодировать данные курсора в интерфейс map[string] {}, я пробовал это напрямую, но он не работает вообще, поэтому я решил, что мне нужно преобразовать его в документ BSON и затем преобразовать его к интерфейсу map[string] {} и, наконец, в строку 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-485d0bebee
И карта анализируется как JSON:
{ "_Id":"5c2d0809a49bad7d547ec028","приложения":[{}],"имя_пользователя": "Кото","userUUID":"df2dea92-c189-53b3-aafe-485d0be23bee"}
Как вы можете видеть, ключ "приложения" в JSON пуст, но он действительно имеет содержание в документе BSON. Я не знаю, почему данные исчезают.
Как я могу решить эту ошибку? Благодарю.
2 ответа
Решено:
Я решил эту ошибку, используя следующий код:
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)
}
temp := itemBson.data.(primitive.D) // convert interface to primitive D
metadata := temp.Map() // map to map[string]interface{}
if v, ok := metadata[prqKey]; ok { // check and use value
commitID = v.(string)
}
Вы можете использовать встроенный интерфейс на primitive.D
введите, чтобы преобразовать его в map[string]interface{}
bson.M
от официального монго-го-водителя pimitive.M
который является типом map[string]interface{}
, Не видя ваших объявленных переменных, трудно сказать, что пошло не так. Вот рабочий пример использования официального mongo-go-driver.
func TestUnmarshal(t *testing.T) {
uri := "mongodb://localhost/stackru?replicaSet=replset"
ctx := context.Background()
client, err := mongo.Connect(ctx, uri)
if err != nil {
t.Fatal(err)
}
c := client.Database("stackru").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]]]