Mongo-go-driver 从插入结果中获取 objectID

Mongo-go-driver get objectID from insert result

在使用 InsertOne 创建新文档后,当我 return 结果时,我得到的是一个数字数组而不是 ObjectID。在数据库中,id 生成正常。

type User struct {
  ID       string
  Email    string
  Username string
  Password string
}

var db = ...

// UserStore creates user
func UserStore(c echo.Context) (err error) {

  coll := db.Collection("users")

  u := new(User)
  if err = c.Bind(u); err != nil {
    return c.JSON(http.StatusInternalServerError, err)
  }

  result, err := coll.InsertOne(
    context.Background(),
    bson.NewDocument(
        bson.EC.String("email", u.Email),
        bson.EC.String("username", u.Username),
        bson.EC.String("password", u.Password),
    ),
  )
  if err != nil {
    return c.JSON(http.StatusInternalServerError, err)
  }

  return c.JSON(http.StatusCreated, result)
}

这个 return 类似于 InsertedID: [90, 217, 85, 109, 184, 249, 162, 204, 249, 103, 214, 121] 而不是正常的 ObjectID。我怎样才能 return 新插入文档中的实际 ObjectID

一个成功的Collection.InsertOne() will return a result of type mongo.InsertOneResult,这是一个包装新插入文档ID的结构体:

type InsertOneResult struct {
    // The identifier that was inserted.
    InsertedID interface{}
}

官方MongoDB Go驱动使用primitive.ObjectID类型来表示MongoDB ObjectIds。这种类型是一个简单的字节数组:

type ObjectID [12]byte

要访问此类型,您需要导入 primitive package

import "go.mongodb.org/mongo-driver/bson/primitive"

InsertOneResult.InsertedID 将包含 primitive.ObjectID 的动态类型。 primitive.ObjectID 类型没有定义自定义的 JSON 封送处理方法(没有实现 json.Marshaler),这意味着当结果转换为 JSON 时,默认的封送处理规则将是使用,对于字节数组(不是切片),您看到的是:ObjectID 字节的十进制表示形式。

您不应该将 InsertOneResult 类型的值转换为 JSON,因为它(或者 primitive.ObjectID 本身)不是 "JSON-friendly"(至少不是当前版本)。

而是创建/包装您自己的类型,在其中定义您希望结果在 JSON 中的样子,例如:

if oid, ok := result.InsertedID.(primitive.ObjectID); ok {
    return c.JSON(http.StatusCreated, map[string]interface{}{
        "id": oid.String(),
    })
} else {
    // Not objectid.ObjectID, do what you want
}

以上代码将导致 JSON 响应如下:

{"id":"ObjectID(\"5ad9a913478c26d220afb681\")"}

或者如果您只想要十六进制表示:

if oid, ok := result.InsertedID.(primitive.ObjectID); ok {
    return c.JSON(http.StatusCreated, map[string]interface{}{
        "id": oid.Hex(),
    })
}

这将是:

{"id":"5ad9a913478c26d220afb681"}