drzbc6003 2019-04-03 08:44
浏览 151

UUID为_id错误-无法将数组用于_id

I'm attempting to use UUIDs for my _id field in a MongoDB.

I have a wrapper struct to hold my record, like so:

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

This is my code around the InsertOne function from the MongoDB driver packages:

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
}

This is my wrap() func that wraps up the payment record data, and takes an optional UUID argument or generates its own accordingly:

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
}

When one of my tests calls Create() it returns the following error:

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

I'm using the following packages for my UUIDs and MongoDB driver:

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

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

I'm not clear on where exactly the problem lies.

Do I need some extra plumbing around the UUID in order for it to be handled correctly?

edit: I made some more changes, but the UUID still comes through as an array:

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条回答 默认 最新

  • doumeikuan6834 2019-04-03 09:01
    关注

    uuid.UUID is a [16]byte under the hood.

    However, this type also implements the encoding.TextMarshaler interface, which I would expect mongo to honor (the same way the json package does).

    I believe the solution is to create your own type, which embeds the uuid.UUID type, and provides a custom implementation of the bson.Marshaler interface.

    评论

报告相同问题?

悬赏问题

  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏