Хранение вложенных структур с помощью mgo
Я пытаюсь построить документ mongo из структуры go, которая сильно вложенна, и я столкнулся с проблемой перехода от go struct к объекту mongo. Я создал очень упрощенную версию того, с чем я пытаюсь работать здесь: http://play.golang.org/p/yPZW88deOa
package main
import (
"os"
"fmt"
"encoding/json"
)
type Square struct {
Length int
Width int
}
type Cube struct {
Square
Depth int
}
func main() {
c := new(Cube)
c.Length = 2
c.Width = 3
c.Depth = 4
b, err := json.Marshal(c)
if err != nil {
panic(err)
}
fmt.Println(c)
os.Stdout.Write(b)
}
Запуск этого вызывает следующий вывод:
&{{2 3} 4}
{"Length":2,"Width":3,"Depth":4}
Это имеет смысл. Кажется, что функция Write или json.Marshal имеет некоторую функциональность, которая сворачивает вложенную структуру, но моя проблема возникает, когда я пытаюсь вставить эти данные в базу данных mongo, используя функцию mgo func (*Collection) Upsert
(http://godoc.org/labix.org/v2/mgo#Collection.Upsert). Если я сначала использую функцию json.Marshal()
и передаю байты в collection.Upsert()
, она сохраняется как двоичная, что я не хочу, но если я использую collection.Upsert(bson.M("_id": id, &c)
, она выглядит как вложенная структура с формой:
{
"Square": {
"Length": 2
"Width": 3
}
"Depth": 4
}
Но то, что я хочу сделать, это upsert to mongo с той же структурой, что и я, когда я использую функцию os.Stdout.Write()
:
{
"Length":2,
"Width":3,
"Depth":4
}
Есть ли какой-то флаг, который мне не хватает, что бы легко справиться с этим? Единственная альтернатива, которую я вижу на этом этапе, - это серьезно сократить читаемость кода, удалив вложенность структур, что я действительно ненавижу делать. Опять же, мой фактический код является более сложным, чем этот пример, поэтому, если я могу избежать еще большего усложнения, удерживая вещи вложенными, это определенно было бы предпочтительным.
Ответы
Ответ 1
Я думаю, что использование тега поля inline
- лучший вариант для вас. В документации mgo/v2/bson указано:
inline Inline the field, which must be a struct or a map,
causing all of its fields or keys to be processed as if
they were part of the outer struct. For maps, keys must
not conflict with the bson keys of other struct fields.
Затем ваша структура должна быть определена следующим образом:
type Cube struct {
Square `bson:",inline"`
Depth int
}
Edit
inline
также существует в mgo/v1/bson
, если вы используете его.