【问题标题】:How to get ObjectID as String from mongo-go-driver cursor?如何从 mongo-go-driver 光标获取 ObjectID 作为字符串?
【发布时间】:2022-02-04 09:08:43
【问题描述】:

我想将 ObjectID 作为字符串获取,因为我有其他存储类型,所以我想避免在我的结构中使用 primitive.ObjectID 以保持层独立。 我是 Golang 新手,谢谢。

package listing

type Card struct {
    ID       string
    Hanzi    string
    Pinyin   string
    Traducao string
}

我的存储文件: 包裹存放

func (m *Mongodb)GetCards() []*listing.Card {
    var list []*listing.Card

    collection := m.Client.Database("flashcards").Collection("cards")
    cur, err := collection.Find(context.TODO(), bson.M{})

    if err != nil {
        log.Fatal("Erro buscando cards:", err)
    }
    for cur.Next(context.TODO()) {
        var card listing.Card
        err = cur.Decode(&card)
        if err != nil {
            log.Fatal("Erro decodificando documento", err)
        }
        list = append(list, &card)
    }
    return list
}

【问题讨论】:

  • 你说的是哪个 ObjectID?

标签: go bson mongo-go


【解决方案1】:

和您一样,我一直在寻找一种解决方案,以使模块尽可能独立并保持低耦合级别。 我挠了很多头,但最后我找到了这个,我希望是有效且清晰的解决方案。

您可以使用实现ValueMarshaler 接口的自定义类型:因此您必须实现 MarshalValue函数!

type Card struct {
    ID       MyObjectID `bson:"_id"`
    CardSuit string     `bson:"cardSuit"`
}

type MyObjectID string

func (id MyObjectID) MarshalBSONValue() (bsontype.Type, []byte, error) {
    p, err := primitive.ObjectIDFromHex(string(id))
    if err != nil {
        return bsontype.Null, nil, err
    }

    return bson.MarshalValue(p)
}

ID 实际上是 string,但使用自定义编组器,它将在 Mongo 中保存为 ObjectID,并在解组时正确解析。

Here a working example,你显然需要 mongo 才能让它运行。

Related question that helped me.

【讨论】:

    【解决方案2】:

    好的,我想通了。 我创建了另一个结构来保存 ObjectId

    type HexId struct {
        ID primitive.ObjectID `bson:"_id"`
    }
    

    然后我使用 Hex() 将值传递给 Card.ID

    err = cur.Decode(&card)
    err = cur.Decode(&hexId)
    card.ID = hexId.ID.Hex()
    

    现在我可以用它来建立链接了。

    【讨论】:

      【解决方案3】:

      对我来说,当有 bson 注释(版本 5.0.6)时,它开箱即用:

      type User struct {
          Id   string `bson:"_id,omitempty" json:"id,omitempty"`
          Name string `bson:"name" json:"name"`
      }
      

      【讨论】:

        【解决方案4】:

        在响应中使用bson:"-" 忽略ObjectID,在数据库中忽略json:"-"。 而且你不需要解码两次。

        type Card struct {
            ObjectID primitive.ObjectID `json:"-" bson:"_id"`
            ID       string             `bson:"-"`
            Hanzi    string
            Pinyin   string
            Traducao string
        }
        
        err = cur.Decode(&card)
        card.ID = card.ObjectID.Hex()
        

        【讨论】:

        • 它可以工作,但正如我所说,我想让我的图层保持独立。我不想在这一层上使用特定于数据库的类型。但是,此解决方案避免了两次解码光标。谢谢 Eklavya
        猜你喜欢
        • 2018-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-16
        • 1970-01-01
        • 2019-05-02
        相关资源
        最近更新 更多