@krotlinman

Как правильно анмаршаллить json из bson.Raw?

Есть следующая модель, которая сохраняется в бд (mongodb):

type Model struct {
    ID      primitive.ObjectID `json:"id" bson:"_id,omitempty"`
    Name    string             `json:"name" bson:"name"`
    Content bson.Raw           `json:"content" bson:"content"`
    Code  int                `json:"status" bson:"status"`
}

есть роут, принимающий запрос на создание модели, в котором я читаю тело запроса и делаю bson.UnmarshalExtJSON() в модель, указанную выше.

пример json на создание модели:
{
    "name": "Tes",
    "content":  
    {
        "value":"test1",
        "second_value":"test2",
        "third_value":"test3",
        "four_value":"test4"
    },
    "code": 2
}

с сохранением всё окей, в бд заносится нормальный порядок элементов объекта "content". но при попытке отдать эту модель возникают сложности. т.к у Content тип bson.Raw, я не могу напрямую его замаршаллить. сделал аналогичную модель, но у поля Content - тип string. заполняю новую модель, поле Content - через метод у bson.Raw - String(). но выходит следующее:
{
        "id": "5fb3cae3c9b63c8acac7b5ac",
        "name": "Tes",
        "content": "{\"value\": \"test1\",\"second_value\": \"test2\",\"third_value\": \"test3\",\"four_value\": \"test4\"}",
        "сode": 2
}

что является не тем, что я ожидал. при попытке json.Unmarshal в какую-нибудь мапу - полностью теряется порядок элементов, хотя в БД он верный.
var result map[string]string
    err = json.Unmarshal([]byte(event.Content.String()), &result)
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(result)

результат:
map[four_value:test4 second_value:test2 third_value:test3 value:test1]

как можно достать данные из БД и замаршаллить их в json в том же виде, в котором они и были, без потери порядка? ключи передаваемого объекта могут быть одинаковыми, что создает дополнительную проблему.
{
    "name": "Tes",
    "content":  
    {
        "value":"test1",
        "value":"test2",
        "value":"test3",
        "value":"test4"
    },
    "code": 2
}

возникла идея индексации, но я совершенно не понимаю, как ее можно реализовать. пробовал что-то вроде ordered maps, но т.к ключи могут быть одинаковыми, он их просто не видит, и отдает одну запись ключ-значение без остальных.
map[value:test4]
пожалуйста, подскажите, как можно решить этот момент?
  • Вопрос задан
  • 145 просмотров
Решения вопроса 1
yellow79
@yellow79
Senior Software Engineer
Вероятно вам придётся написать собственный маршаллер для своей структуры, что-то примерно вот такое:
https://play.golang.com/p/K2JkfIiWKvh
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы