UUID as _id error - невозможно использовать массив для _id - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь использовать UUID для моего поля _id в MongoDB.

У меня есть структура-обертка для хранения моей записи, например:

type mongoWrapper struct {
    ID      uuid.UUID       `bson:"_id" json:"_id"`
    Payment storage.Payment `bson:"payment" json:"payment"`
}

Этомой код вокруг функции InsertOne из пакетов драйверов MongoDB:

func (s *Storage) Create(newPayment storage.Payment) (uuid.UUID, error) {
    mongoInsert := wrap(newPayment)
    c := s.client.Database(thisDatabase).Collection(thisCollection)

    insertResult, errInsert := c.InsertOne(context.TODO(), mongoInsert)
    if errInsert != nil {
        return uuid.Nil, errInsert
    }

    fmt.Println("Inserted a single document: ", insertResult.InsertedID)

    return mongoInsert.ID, nil
}

Это мой метод wrap (), который оборачивает данные записи платежа и принимает необязательный аргумент UUID или генерирует свой собственный соответственно:

func wrap(p storage.Payment, i ...uuid.UUID) *mongoWrapper {
    mw := &mongoWrapper{ID: uuid.Nil, Payment: p}

    if len(i) > 0 {
        mw.ID = i[0]
        return mw
    }

    newID, errID := uuid.NewV4()
    if errID != nil {
        log.Fatal(errID)
    }

    mw.ID = newID

    return mw
}

Когда один из моих тестов вызывает Create (), он возвращает следующую ошибку:

storage_test.go:38: err: multiple write errors: [{write errors: [{can't use an array for _id}]}, {<nil>}]

Я использую следующие пакеты для моих UUID и драйвера MongoDB:

import(
    uuid "github.com/satori/go.uuid"

    "go.mongodb.org/mongo-driver/mongo"
)

Мне непонятно, в чем именно заключается проблема.

Нужна ли дополнительная сантехника вокруг UUID для правильной обработки?

edit: Я сделал еще несколько изменений, но UUID все еще выглядит как массив:

type mongoWrapper struct {
    UUID    mongoUUID       `bson:"uuid" json:"uuid"`
    Payment storage.Payment `bson:"payment" json:"payment"`
}

type mongoUUID struct {
    uuid.UUID
}

func (mu *mongoUUID) MarshalBSON() ([]byte, error) {
    return []byte(mu.UUID.String()), nil
}

func (mu *mongoUUID) UnmarshalBSON(b []byte) error {
    mu.UUID = uuid.FromStringOrNil(string(b))
    return nil
}

1 Ответ

1 голос
/ 03 апреля 2019

uuid.UUID - это [16]byte под капотом.

Однако этот тип также реализует интерфейс encoding.TextMarshaler, который, как я ожидаю, будет соблюдать Монго (так же, как пакет json).

Я считаю, что решение состоит в том, чтобы создать свой собственный тип, который включает тип uuid.UUID и обеспечивает пользовательскую реализацию интерфейса bson.Marshaler .

...