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"}
在使用 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"}