Запрос записи, которая была вставлена ​​драйвером C # с определением _t - PullRequest
1 голос
/ 09 мая 2019

Я хочу запросить данные, которые были вставлены C # mongodriver с полиморфизмом. Запрос будет сделан драйвером Golang. Структура данных показана ниже. Я хочу отобразить _t на структуры, другими словами, я хочу применить полиморфизм для записи в Go. Можно ли это сделать в драйверах Golang Mongo? Список структур также ниже.

Один пример записи из коллекции Монго

{"_id" : "asdasda12312312asdasda",
"structure" : [ 
                    {
                        "_t" : "AObject",
                        "Text" : "asdasdasda",
                        "State" : "asdasda"
                    }, 
                    {
                        "_t" : "BObject",
                        "Number" : "123",
                    }, 
                    {
                        "_t" : "CObject",
                        "Testing" : "Pompeo"
                    }
                ]
}

Go Structs

type Data struct{
  _id string
  Structure []Object
}

type Object interface{
}

type AObject struct {
  Text  string
  State string 
}
type BObject struct {
  Number  string 
}
type CObject struct {
  Testing  string
}

Спасибо

Ответы [ 2 ]

1 голос
/ 09 мая 2019

Какой драйвер Монго вы используете?«_t» - это параметр, используемый для определения того, какой тип был сериализован, если текущий тип отличается от номинального типа.Он также используется для обычной сериализации JSON, поэтому у меня есть один из трех способов, о которых я могу подумать.

  1. Использование другого драйвера GO mongo, который его поддерживает.Я бы предложил использовать https://github.com/mongodb/mongo-go-driver, который является официальным драйвером MongoDB Go
  2. Написать оператор switch / case, чтобы десериализовать его самостоятельно
type MongoObject struct {
        // Contains all fields from all objects
        _t string
        Text string
        State string
        Number string
        Testing string
}

func DeserializeObject(object MongoObject) Object{
        switch t {
        case "AObject":
        return &AObject{Text: object.Text, State: object.State}
        case "BObject":
        return &BObject{Number: object.Text}
        case "CObject":
        return &CObject{Testing: object.Testing}
    }
}
Вы можете получать данные из mongo как JSON и использовать определенный маршалинг, чтобы сделать это за вас
0 голосов
/ 09 мая 2019

Использование интерфейсов, как правило, проблематично, поскольку библиотекам, выполняющим демаршалинг, будет трудно решить, какой тип выбрать. Вы можете использовать собственный unmarshaler, в котором вы выбираете подходящий тип, но это более громоздко и сложно.

Проще всего использовать конкретные типы конструкций. Вы должны использовать теги struct для отображения структурных полей и полей в документах MongoDB. Одна важная вещь состоит в том, что в Go поля должны быть экспортированы, иначе они не могут быть заполнены / прочитаны библиотеками, которые выполняют работу. Для его экспорта их имя должно начинаться с заглавной буквы, а подчеркивание (_) не входит в их число.

Если (под) документы могут иметь разные поля в зависимости от значения, вы можете добавить все, и те, которые присутствуют, будут должным образом не разбиты.

Ваш документ может быть смоделирован так:

type Data struct {
    ID        string   `bson:"_id"`
    Structure []Object `bson:"structure"`
}

type Object struct {
    T       string `bson:"_t"`
    Text    string `bson:"Text,omitempty"`
    State   string `bson:"State,omitempty"`
    Number  string `bson:"Number,omitempty"`
    Testing string `bson:"Testing,omitempty"`
}

Обратите внимание, что опция ,omitempty не требуется для демаршалинга, но если вы хотите использовать эти же типы для марсалирования (например, сохранение нового документа), опция ,omitempty обеспечит пропуск полей, которые пусты.

Также обратите внимание, что если вас это не устраивает, ничто не мешает вам обработать результат. Вы можете включить доступное поле Object.T и создать «динамические» экземпляры типов по вашему выбору.

...