Частичные обновления с использованием вложенных структур с помощью go/mgo

Я пытаюсь максимизировать повторное использование кода в объектах, которые совместно используют данные, используя вложенные структуры. Рассмотрим следующий код:

package main

import (
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
)

var collection *mgo.Collection

type Identifiable interface {
    GetId() bson.ObjectId
}

type A struct {
    Id bson.ObjectId `bson:"_id"`
    A_value int
}

type B struct {
    A `bson:",inline"`
    B_value int
}

func (self *A) GetId() bson.ObjectId {
    return self.Id
}

func setAValue(value int, a *A) {
    a.A_value = value
    commit(a)
}

func commit(i Identifiable) {
    collection.UpsertId(i.GetId(), i)
}

func main() {
    session, _ := mgo.Dial("localhost")
    collection = session.DB("test").C("my_collection")

    b := B{A: A{Id: bson.NewObjectId(), A_value: 1}, B_value: 2}
    commit(&b)
}

На данный момент запись в монго выглядит так (как я и ожидал):

{ "_id": ObjectId ("54f0e231eefbfe049c000001"), "a_value": 1, "b_value": 2}

Но тогда я хотел бы сделать что-то подобное, чтобы не писать лишние функции:

setAValue(42, &b.A)

Проблема в том, что это приводит к потере данных, поскольку заменяет всю запись, а не просто обновляет ее:

{ "_id": ObjectId ("54f0df4eeefbfe0474000001"), "a_value": 42}

Есть ли способ выполнить подобное обновление, не удаляя все значения, не принадлежащие A? Или я просто иду по этому пути совершенно неправильно?


person Chris    schedule 27.02.2015    source источник


Ответы (1)


Проблема заключается в том, что setAValue вы фиксируете тип A, а не B. Недавно зафиксированное значение BSON не содержит B_value.

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

person Jaemin Park    schedule 28.02.2015