Inserting data into MongoDB with mgo
Asked Answered
T

3

11

I'm trying to insert some data in MongoDB using Go.

Here is the data struct:

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"`
}

This is my insert function:

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

And finally, this is how I call it:

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

The trouble is, I was expecting my bson tags to magically work, but they don't. Instead of data being saved as:

{ "_id" : ObjectId("53700d9cd83e146623e6bfb4"), "resource_id" : 7660708, "word" : "Foo" ...}

It gets saved as:

{ "_id" : ObjectId("53700d9cd83e146623e6bfb4"), "id" : "", "resourceid" : 7660708, "word" : "Foo"...}

How can I fix this?

Tiossem answered 11/5, 2014 at 23:59 Comment(0)
M
15

Change entry to:

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"`
}

The syntax for Struct Tags does not use commas between tags. I believe this should fix it.

Martres answered 12/5, 2014 at 2:40 Comment(3)
this is wrong. not only does Id need to be of type bson.ObjectId but the bson tags aren't necessary except for ResourceId which does not get autoconverted to "resource_id". Uppercase struct fields get lowercased by mgo. Only the json lowercase field name is needed.Fresher
@dalu The _id can actually be of any type. Edit: Well, unless the OP did expect an ObjectId, which isn't entirely clear from the question.Scheldt
@dalu as Gustavo said, the _id does not need to be an ObjectId, That is the default, but not always the required choice. Also, nothing is wrong. I personally think that including the bson struct tag is better practice in the long run even if it is the same. Imagine if a future dev comes along and decides to change the variable "Word" to "Title". Without defining the bson tag, they would be altering the datastore without realizing it. Keeping a bson tag helps maintenance down the line IMO and at worse, makes you type a few more characters for clarity.Martres
F
8
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"`
}

Instead of Count() and Insert() you can use UpsertId which does just that, if an Id exists the record is replaced if not it's inserted.

Insert() with an empty ObjectId lets MongoDB handle Id assignment.

Edit: Misread your Count query. You also have an error in there. It should be "resource_id" not "resourceid" because you declared that the bson field is named "resource_id"

Fresher answered 12/5, 2014 at 2:49 Comment(4)
The way how insertEntry works may seem counter-intuitive, but it makes sense in the way the program works.Tiossem
yes, corrected that. I thought you were checking if an objectId existed then insert a new record.Fresher
wtf that's the correct answer. Id needs to be bson.ObjectIdFresher
If we dont insert object id mongo will create a default _id parameterDay
S
0

Update your Entry struct as:

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"`
}

This should work!

Stick answered 11/5, 2019 at 23:19 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.