вложенная структура в mongodb

Использую следующие пакеты:

"gopkg.in/mgo.v2"

"gopkg.in/mgo.v2/bson"

Я пытаюсь обработать вложенную структуру и поместить ее в mongodb. Следующий код выполняет свою работу правильно, но я не знаю, правильно ли это.

// init
type DummyStruct struct {
    User     string  `bson:"user"`
    Foo      FooType `bson:"foo"`
}

type FooType struct {
    BarA int `bson:"bar_a"`
    BarB int `bson:"bar_b"`
}


//  main
foobar := DummyStruct{
    User: "Foobar",
    Foo: FooType{
        BarA: 123,
        BarB: 456,
    },
}

// Insert
if err := c.Insert(foobar); err != nil {
    panic(err)
}

Нужно ли строить вложенную структуру из 2 частей?

Если я использую преобразователь структуры json-> golang (https://mholt.github.io/json-to-go/)

Я получу следующую структуру

type DummyStructA struct {
    User string `bson:"user"`
    Foo  struct {
        BarA int `bson:"bar_a"`
        BarB int `bson:"bar_b"`
    } `bson:"foo"`
}

Теперь я не знаю, как мне заполнить эту структуру.

Я пробовал это:

foobar := DummyStructA{
    User: "Foobar",
    Foo: {
        BarA: 123,
        BarB: 456,
    },
}

но получил эту ошибку: отсутствует тип в составном литерале

Я тоже пробовал это

foobar := DummyStructA{
    User: "Foobar",
    Foo{
        BarA: 123,
        BarB: 456,
    },
}

и получил 2 ошибки:

  • смесь полей: значение и инициализаторы значения

  • undefined: Foo

Или необходимо обрабатывать структуру (DummyStructA) с помощью bson.M?


person overboarded    schedule 19.01.2018    source источник


Ответы (2)


Вы можете сделать это вот так

package main

import (
    "fmt"
    "encoding/json"
)

type DummyStruct struct {
    User     string  `bson:"user" json:"user"`
    Foo      FooType `bson:"foo" json:"foo"`
}

type FooType struct {
    BarA int `bson:"barA" json:"barA"`
    BarB int `bson:"bar_b" json:"bar_b"`
}

func main() {
    test:=DummyStruct{}
    test.User="test"
    test.Foo.BarA=123
    test.Foo.BarB=321
    b,err:=json.Marshal(test)
    if err!=nil{
        fmt.Println("error marshaling test struct",err)
        return
    }
    fmt.Println("test data\n",string(b))
}

OutPut похож на это

test data
{"user":"test","foo":{"barA":123,"bar_b":321}}

Попробуйте на игровой площадке: https://play.golang.org/p/s32pMvqP6Y8

person negi Yogi    schedule 19.01.2018
comment
спасибо, это действительно здорово и работает также с большой структурой :) - person overboarded; 19.01.2018
comment
да, просто сохранить разные структуры и легко декодировать данные, если они поступают из API. - person negi Yogi; 19.01.2018

Если вы определяете 2 разные структуры, как в вашем вопросе. Вам нужно объявить foobar как:

foobar := DummyStructA{
User: "Foobar",
Foo: FooType{
    BarA: 123,
    BarB: 456,
},

}

Но нет необходимости определять второй тип для обработки этого сценария. Вы можете использовать анонимный struct, например:

type DummyStructA {
    User string `bson:"user"`
    Foo struct{
       Name string `bson:"name"`
       Age int `bson:"age"`
    } `bson: "foo"`
}

Но это становится громоздким при попытке заполнить данные.

foobar := DummyStructA{
     User: "hello",
     Foo : struct{
           Name string
           Age int
         }{
         Name: "John",
         Age: 50,
     }
}
person KBN    schedule 19.01.2018
comment
Спасибо за ответ. Это означает, что два необходимых элемента обрабатывают это в отдельных структурах, таких как мой первый пример, чтобы иметь хороший дескриптор при заполнении этого? Для меня это не так гладко: D - person overboarded; 19.01.2018
comment
Да, у вас должны быть разные структуры, как у вас уже было, чтобы упростить задачу. - person KBN; 19.01.2018