英文:
Additional "id" field generated when posting into MongoDB
问题
我正在学习Go和Gin框架。
我构建了一个简单的微服务,连接到一个MongoDB集合,一切都正常,但是当我使用POST方法添加一个文档时,它添加了"id"字段而不是生成键"_id"字段,有没有办法避免这种情况?
这是我的函数:
func (r *Rest) CreatePost(c *gin.Context) {
var postCollection = database.GetCollection(r.db, "GoDB")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
post := new(model.Post)
defer cancel()
if err := c.ShouldBindJSON(&post); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": err})
log.Fatal(err)
return
}
// 验证
if err := post.Validate(); err == nil {
c.JSON(http.StatusOK, gin.H{"input": "valid"})
} else {
c.JSON(http.StatusBadRequest, gin.H{"input validation": err.Error()})
return
}
postPayload := model.Post{
ID: primitive.NewObjectID(),
Title: post.Title,
Article: post.Article,
}
result, err := postCollection.InsertOne(ctx, postPayload)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Posted succesfully", "Data":
map[string]interface{}{"data": result}})
}
这是我的模型:
type Post struct {
ID primitive.ObjectID
Title string `validate:"required,gte=2,lte=20"`
Article string `validate:"required,gte=4,lte=40"`
}
理解这个问题需要返回的Mongo文档如下图所示:
英文:
I'm learning Go and Gin framework.
I built a simple microservice connected to a MongoDB collection, everything works but when I add a document using a POST it adds the "id" field instead of generating the key "_id" field, is there a way to avoid this?
This is my func:
func (r *Rest) CreatePost(c *gin.Context) {
var postCollection = database.GetCollection(r.db, "GoDB")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
post := new(model.Post)
defer cancel()
if err := c.ShouldBindJSON(&post); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": err})
log.Fatal(err)
return
}
// validation
if err := post.Validate(); err == nil {
c.JSON(http.StatusOK, gin.H{"input": "valid"})
} else {
c.JSON(http.StatusBadRequest, gin.H{"input validation": err.Error()})
return
}
postPayload := model.Post{
ID: primitive.NewObjectID(),
Title: post.Title,
Article: post.Article,
}
result, err := postCollection.InsertOne(ctx, postPayload)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Posted succesfully", "Data":
map[string]interface{}{"data": result}})
}
This is my model:
type Post struct {
ID primitive.ObjectID
Title string `validate:"required,gte=2,lte=20"`
Article string `validate:"required,gte=4,lte=40"`
}
答案1
得分: 0
默认情况下,ID
的键是 id
。你应该使用 bson
标签来生成键 _id
。
type Post struct {
ID primitive.ObjectID `bson:"_id"`
Title string `validate:"required,gte=2,lte=20"`
Article string `validate:"required,gte=4,lte=40"`
}
这里是文档:
在编组结构时,每个字段都会转换为小写以生成相应 BSON 元素的键。例如,名为 "Foo" 的结构字段将生成键 "foo"。可以通过结构标签进行覆盖(例如,
bson:"fooField"
生成键 "fooField")。
当文档中不包含名为 _id
的元素时,驱动程序会自动添加一个(参见源代码):
// ensureID inserts the given ObjectID as an element named "_id" at the
// beginning of the given BSON document if there is not an "_id" already. If
// there is already an element named "_id", the document is not modified. It
// returns the resulting document and the decoded Go value of the "_id" element.
func ensureID(
doc bsoncore.Document,
oid primitive.ObjectID,
bsonOpts *options.BSONOptions,
reg *bsoncodec.Registry,
) (bsoncore.Document, interface{}, error) {
这是一个示例:
package main
import (
"context"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Post struct {
ID primitive.ObjectID `bson:"_id"`
Title string `validate:"required,gte=2,lte=20"`
Article string `validate:"required,gte=4,lte=40"`
}
func main() {
client, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost"))
if err != nil {
panic(err)
}
postCollection := client.Database("demo").Collection("posts")
post := Post{
ID: primitive.NewObjectID(),
Title: "test title",
Article: "test content",
}
if _, err = postCollection.InsertOne(context.Background(), post); err != nil {
panic(err)
}
}
在数据库中创建的文档如下:
demo> db.posts.find()
[
{
_id: ObjectId("64a53bcbb7be31ae42e6c00c"),
title: 'test title',
article: 'test content'
}
]
英文:
By default, the key for ID
is id
. You should use the bson
tag to generate the key _id
instead.
type Post struct {
ID primitive.ObjectID `bson:"_id"`
Title string `validate:"required,gte=2,lte=20"`
Article string `validate:"required,gte=4,lte=40"`
}
Here is the doc:
> When marshalling a struct, each field will be lowercased to generate the key for the corresponding BSON element. For example, a struct field named "Foo" will generate key "foo". This can be overridden via a struct tag (e.g. bson:"fooField"
to generate key "fooField" instead).
When the document does not contain an element named _id
, the driver will add one automatically (see the source code):
// ensureID inserts the given ObjectID as an element named "_id" at the
// beginning of the given BSON document if there is not an "_id" already. If
// there is already an element named "_id", the document is not modified. It
// returns the resulting document and the decoded Go value of the "_id" element.
func ensureID(
doc bsoncore.Document,
oid primitive.ObjectID,
bsonOpts *options.BSONOptions,
reg *bsoncodec.Registry,
) (bsoncore.Document, interface{}, error) {
Here is a demo:
package main
import (
"context"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Post struct {
ID primitive.ObjectID `bson:"_id"`
Title string `validate:"required,gte=2,lte=20"`
Article string `validate:"required,gte=4,lte=40"`
}
func main() {
client, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost"))
if err != nil {
panic(err)
}
postCollection := client.Database("demo").Collection("posts")
post := Post{
ID: primitive.NewObjectID(),
Title: "test title",
Article: "test content",
}
if err != nil {
panic(err)
}
if _, err = postCollection.InsertOne(context.Background(), post); err != nil {
panic(err)
}
}
And the document created in the database:
demo> db.posts.find()
[
{
_id: ObjectId("64a53bcbb7be31ae42e6c00c"),
title: 'test title',
article: 'test content'
}
]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论