Search code examples
mongodbgobson

Add Fields to MongoDB Inner Object


I'm trying to append fields to an object in my mongodb collection. So far this is what my document in MongoDB looks like.

enter image description here

My users can have multiple devices so I'm trying to append more fields to the devices object. I have tried to use $push for an array instead of an object but I didn't like how I would have to access the data later on when I retrieve it from the database.

So I started to use $set. $set works great because it gives me the format in which I want my data to save in the db but it will continually override my one key value pair in the devices object every time and I don't want that to happen.

db.go

func AddDeviceToProfile(uid string, deviceId int, deviceName string) {
    client := ConnectClient()
    col := client.Database(uid).Collection("User")

    idString := strconv.Itoa(deviceId)

    filter := bson.M{"uid": uid}

    update := bson.M{
        "$set": bson.M{"devices": bson.M{idString: deviceName}}, <------ Need to fix this 
    }

    option := options.FindOneAndUpdate()

    _ = col.FindOneAndUpdate(context.TODO(), filter, update, option)

    log.Print("Device Added")
    _ = client.Disconnect(context.TODO())
}

I have looked into using $addFields but I don't know if I was doing it correctly I just replaced $set above and added $addFields and I also tried it this way

update := bson.M{
        "devices": bson.M{"$addFields": bson.M{idString: deviceName}},
    }

What I want my document to look like

enter image description here


Solution

  • Instead of using $push or $addFields what you need is $set directive.

    To specify a field in an embedded document, use dot notation.

    For the document matching the criteria _id equal to 100, the following operation updates the make field in the devices document:

    db.products.update(
       { _id: 100 },
       { $set: { "devices.make": "zzz" } }
    )
    

    Converting them to Go syntax is easy as well. What you are doing is correct. The following should work or might require a little bit of tweaking.

    func AddDeviceToProfile(uid string, deviceId int, deviceName string) {
        client := ConnectClient()
        col := client.Database(uid).Collection("User")
    
        idString := strconv.Itoa(deviceId)
    
        filter := bson.M{"uid": uid}
    
        update := bson.M{"$set": bson.M{"devices." + idString: deviceName}}
    
        option := options.FindOneAndUpdate()
    
        _ = col.FindOneAndUpdate(context.TODO(), filter, update, option)
    
        log.Print("Device Added")
        _ = client.Disconnect(context.TODO())
    }