使用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)
}
这会返回InsertedID: [90, 217, 85, 109, 184, 249, 162, 204, 249, 103, 214, 121]
而不是正常的ObjectID
。如何从新插入的文档中返回实际的ObjectID
?
答案 0 :(得分:8)
成功的Collection.InsertOne()
将返回类型为mongo.InsertOneResult
的结果,这是一个包装新插入文档的ID的结构:
type InsertOneResult struct {
// The identifier that was inserted.
InsertedID interface{}
}
官方MongoDB Go驱动程序使用objectid.ObjectID
类型来表示MongoDB ObjectIds。这种类型是一个简单的字节数组:
type ObjectID [12]byte
InsertOneResult.InsertedID
将保留动态类型objectid.ObjectID
。 objectid.ObjectID
类型没有定义自定义JSON编组方法(不实现json.Marshaler
),这意味着当结果转换为JSON时,将使用默认编组规则,对于字节数组(你看到的不是切片):ObjectID字节的十进制表示。
您不应将类型InsertOneResult
的值转换为JSON,因为它(或更确切地说objectid.ObjectID
本身)不是“JSON友好”(至少在当前版本中不是这样)。
而是创建/包装您自己的类型,您可以在其中定义结果在JSON中的显示方式,例如:
if oid, ok := result.InsertedID.(objectid.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.(objectid.ObjectID); ok {
return c.JSON(http.StatusCreated, map[string]interface{}{
"id": oid.Hex(),
})
}
这将是:
{"id":"5ad9a913478c26d220afb681"}