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

kue*_*kue 6 json http go mongodb mongo-go

InsertOne用于创建新文档之后,当我返回结果时,我得到的是数组而不是数字ObjectID.在DB中,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)
}
Run Code Online (Sandbox Code Playgroud)

这会返回类似于InsertedID: [90, 217, 85, 109, 184, 249, 162, 204, 249, 103, 214, 121]正常的内容ObjectID.如何ObjectID从新插入的文档中返回实际值?

icz*_*cza 13

成功Collection.InsertOne()将返回type的结果mongo.InsertOneResult,这是一个包装新插入文档的ID的结构:

type InsertOneResult struct {
    // The identifier that was inserted.
    InsertedID interface{}
}
Run Code Online (Sandbox Code Playgroud)

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

type ObjectID [12]byte
Run Code Online (Sandbox Code Playgroud)

InsertOneResult.InsertedID将持有动态类型primitive.ObjectID.该primitive.ObjectID类型没有定义自定义JSON编组方法(未实现json.Marshaler),这意味着当结果转换为JSON时,将使用默认编组规则,对于字节数组(不是切片),您可以看到:小数表示ObjectID的字节.

您不应该将type的值转换InsertOneResult为JSON,因为它(或者更确切地说,它primitive.ObjectID本身)不是"JSON友好的"(至少在当前版本中不是这样).

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

import "go.mongodb.org/mongo-driver/bson/primitive"
Run Code Online (Sandbox Code Playgroud)

上面的代码会产生如下的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
}
Run Code Online (Sandbox Code Playgroud)

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

{"id":"ObjectID(\"5ad9a913478c26d220afb681\")"}
Run Code Online (Sandbox Code Playgroud)

这将是:

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

  • 答案是正确的,要获取`objectid`,您可以使用primitive.`primitive.ObjectIDFromHex("your generated hex")`,它将返回`ibjectid`而不是十六进制字符串表示形式。 (2认同)