Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ObjectID automatically set to "0...0" in go with official mongoDB driver

Tags:

mongodb

go

I'm trying to save user entries in a MongoDB database with Go. Users should get an ID automatically. I'm using the offical MongoDB Go driver.

My sources were especially https://vkt.sh/go-mongodb-driver-cookbook/ and https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial.

Struct looks like this:

type User struct {
    ID primitive.ObjectID `json:"_id" bson:"_id"`
    Fname string `json:"fname" bson:"fname"`
    Lname string `json:"lname" bson:"lname"`
    Mail string `json:"mail" bson:"mail"`
    Password string `json:"password" bson:"password"`
    Street string `json:"street" bson:"street"`
    Zip string `json:"zip" bson:"zip"`
    City string `json:"city" bson:"city"`
    Country string `json:"country" bson:"country"`
}

Setting up the database (connection works) and signing up users (based on an HTTP-Request r with a user in it's body):

ctx := context.Background()
uriDB := "someURI"
clientOptions := options.Client().ApplyURI(uriDB)
client, err := mongo.Connect(ctx, clientOptions)
collection := client.Database("guDB").Collection("users")

...

var user User
err := json.NewDecoder(r.Body).Decode(&user)

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := collection.InsertOne(ctx, user)
...

When I enter the first user, it is added to the collection, but the ID looks like this: _id:ObjectID(000000000000000000000000)

If I now want to enter another user, I get the following error:

multiple write errors: [{write errors: [{E11000 duplicate key error collection: guDB.users index: _id_ dup key: { : ObjectId('000000000000000000000000') }}]}, {<nil>}]

So it seems like again ObjectID 000000000000000000000000 is assigned.

I expected the ID to be automatically set to a unique value for each entry.

Do I have to manually set the ID or how can I assign unique IDs to users?

like image 528
StefanK Avatar asked Sep 03 '19 17:09

StefanK


2 Answers

Per the documentation you linked, you must set the object ID yourself when using structs:

_, err := col.InsertOne(ctx, &Post{
    ID:        primitive.NewObjectID(),    // <-- this line right here
    Title:     "post",
    Tags:      []string{"mongodb"},
    Body:      `blog post`,
    CreatedAt: time.Now(),
})

The examples before that using bson.M don't need to specify an ID because they don't send the _id field at all; with a struct, the field is being sent with its zero value (as you've seen).

like image 103
Adrian Avatar answered Oct 17 '22 04:10

Adrian


If you set a document _id, mongodb will use that _id for the document during insertion and will not generate. You have to either omit it, or set it manually with primitive.NewObjectID().

like image 43
Burak Serdar Avatar answered Oct 17 '22 05:10

Burak Serdar