我正在学习围棋和杜松子wine 框架. 我构建了一个连接到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
}

// 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}})
}

这是我的模型:

type Post struct {
ID      primitive.ObjectID
Title   string `validate:"required,gte=2,lte=20"`
Article string `validate:"required,gte=4,lte=40"`
}

To understand this is the returned doc from Mongo

推荐答案

默认情况下,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"`
}

以下是前doc名:

在封送 struct 时,每个字段都将被降低以生成相应BSON元素的键.例如,名为"foo"的 struct 字段将生成键"foo".这可以通过 struct 标记来覆盖(例如,使用bson:"fooField"来生成关键字"fooField").

当文档不包含名为_id的元素时,驱动程序将自动添加一个(参见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) {

以下是一个演示:

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)
    }
}

以及在数据库中创建的文档:

demo> db.posts.find()
[
  {
    _id: ObjectId("64a53bcbb7be31ae42e6c00c"),
    title: 'test title',
    article: 'test content'
  }
]

Mongodb相关问答推荐

MongoDB合并按键更新值的对象数组

Mongo Aggregate管道-另一个集合中的多个查找

如何填充Mongoose中的嵌套引用

匹配/筛选/投影对象中数组中数组中的嵌套字段

Mongoose 排除数组中包含特定嵌套对象的文档

MongoDB 对特定搜索查询的响应时间较长

Mongo查找条件:不存在

spring-data-mongodb 上的 TopN 聚合

根据聚合管道MongoDB Atlas触发器中的条件更新多个字段

使用 $addFields 将字段添加到 $lookup 结果中的每个项目

如何构建我只需要打开一次 mongodb 连接的快速应用程序?

Spring Mongodb @DBREF

如何返回 MongoDB 中文档的 ObjectId 或 _id?和错误$in 需要一个数组

RoR3 上的 Mongoid:1)如何在查询中返回特定字段? 2)需要什么 inverse_of ?

有没有办法为 mongoose.js 聚合提供 allowDiskUse 选项?

将 mongodb 聚合框架结果导出到新集合

REACT 获取发布请求

Ruby 按键值分组哈希

MongoDB:如何在 100 个集合中找到 10 个随机文档?

如何使用 Pymongo 在 MongoDB 中 Select 单个字段?