使用 mgo 将数据插入 MongoDB

Posted

技术标签:

【中文标题】使用 mgo 将数据插入 MongoDB【英文标题】:Inserting data into MongoDB with mgo 【发布时间】:2014-06-29 05:41:46 【问题描述】:

我正在尝试使用 Go 在 MongoDB 中插入一些数据。

这是数据结构:

type Entry struct 
    Id          string `json:"id",bson:"_id,omitempty"`
    ResourceId  int    `json:"resource_id,bson:"resource_id"`
    Word        string `json:"word",bson:"word"`
    Meaning     string `json:"meaning",bson:"meaning"`
    Example     string `json:"example",bson:"example"`

这是我的插入函数:

func insertEntry(db *mgo.Session, entry *Entry) error 
    c := db.DB(*mongoDB).C("entries")
    count, err := c.Find(bson.M"resourceid": entry.ResourceId).Limit(1).Count()
    if err != nil 
        return err
    
    if count > 0 
        return fmt.Errorf("resource %s already exists", entry.ResourceId)
    
    return c.Insert(entry)

最后,我是这样称呼它的:

entry := &Entry
    ResourceId:  resourceId,
    Word:        word,
    Meaning:     meaning,
    Example:     example,

err = insertEntry(db, entry)
if err != nil 
    log.Println("Could not save the entry to MongoDB:", err)

问题是,我期待我的bson 标签能神奇地工作,但事实并非如此。 而不是将数据保存为:

"_id" : ObjectId("53700d9cd83e146623e6bfb4"), "resource_id" : 7660708, “单词” : “Foo” ...

它被保存为:

"_id" : ObjectId("53700d9cd83e146623e6bfb4"), "id" : "", “resourceid”:7660708,“word”:“Foo”...

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

将条目更改为:

type Entry struct 
    Id          string `json:"id" bson:"_id,omitempty"`
    ResourceId  int    `json:"resource_id" bson:"resource_id"`
    Word        string `json:"word" bson:"word"`
    Meaning     string `json:"meaning" bson:"meaning"`
    Example     string `json:"example" bson:"example"`

结构标签的语法在标签之间不使用逗号。我相信这应该可以解决它。

【讨论】:

这是错误的。 Id 不仅需要是 bson.ObjectId 类型,而且 bson 标签不是必需的,除了 ResourceId 不会自动转换为“resource_id”。大写结构字段被 mgo 小写。只需要json小写的字段名。 @dalu _id 实际上可以是任何类型。编辑:好吧,除非 OP 确实期望一个 ObjectId,这从问题中并不完全清楚。 @dalu 正如 Gustavo 所说,_id 不需要是 ObjectId,这是默认设置,但并不总是必需的选择。此外,没有什么是错的。我个人认为,从长远来看,包含 bson struct 标签是更好的做法,即使它是相同的。想象一下,如果未来的开发人员出现并决定将变量“Word”更改为“Title”。如果不定义 bson 标签,他们将在不知不觉中更改数据存储。保留 bson 标签有助于维护 IMO,更糟糕的是,为了清晰起见,您还需要输入更多字符。【参考方案2】:
type Entry struct 
    Id          bson.ObjectId `bson:"_id,omitempty" json:"id"`
    ResourceId  int           `json:"resource_id" bson:"resource_id"`
    Word        string        `json:"word"`
    Meaning     string        `json:"meaning"`
    Example     string        `json:"example"`

您可以使用 UpsertId 来代替 Count() 和 Insert(),它就是这样做的,如果存在 Id,则替换记录,如果不插入则替换。

带有空 ObjectId 的 Insert() 让 MongoDB 处理 Id 分配。

编辑: 误读了您的 Count 查询。 你那里也有错误。 它应该是“resource_id”而不是“resourceid”,因为您声明 bson 字段名为“resource_id”

【讨论】:

insertEntry 的工作方式可能看起来有悖常理,但在程序的工作方式上却很有意义。 是的,更正了。我以为你在检查 objectId 是否存在然后插入一条新记录。 wtf 那是正确的答案。 Id 需要是 bson.ObjectId 如果我们不插入对象 id mongo 将创建一个默认的 _id 参数【参考方案3】:

将您的 Entry 结构更新为:

type Entry struct 
    Id          string `bson:"_id"`
    ResourceId  int    `json:"resource_id,omitempty"`
    Word        string `json:"word,omitempty"`
    Meaning     string `json:"meaning,omitempty"`
    Example     string `json:"example,omitempty"`

这应该可行!

【讨论】:

以上是关于使用 mgo 将数据插入 MongoDB的主要内容,如果未能解决你的问题,请参考以下文章

如何取消引用mgo中的dbref?

如何使用 Go 驱动程序或 mgo/qmgo 在 MongoDB 中存储地理空间数据?

即使不为空,Mgo 也会忽略字段

维护 mgo 会话的最佳实践

mgo中的Golang Bson排序参数

golang:mgo剖析之Session