Search code examples
arraysmongodbgomongo-go

Adding new values to an array from another array of same type MongoDB-GO


I'm currently working with the mongodb driver on golang and trying to add fields to a document's array from an input array of the same type:

type Organization struct {
    ID string `bson:"_id,omitempty" json:"id,omitempty" `
    Name string `bson:"name,omitempty" json:"name,omitempty" validate:"required"`
    Members []Member `bson:"members,omitempty" json:"members,omitempty" validate:"required"`
    Owner string `bson:"owner,omitempty" json:"owner,omitempty" validate:"required"`
    CreatedAt *time.Time `bson:"created_at,omitempty" json:"created_at,omitempty"`
    UpdatedAt *time.Time `bson:"updated_at,omitempty" json:"updated_at,omitempty"`
}

type Member struct {
    UserID string `bson:"user_id" json:"user_id" validate:"required"`
    Permissions []string `bson:"permissions" json:"permissions" validate:"required"`
    AddedBy string `bson:"added_by" json:"added_by" validate:"required"`
    Status string `bson:"status" json:"status" validate:"required"`
    AddedAt time.Time `bson:"added_at" json:"added_at"`
}

Specifically I'm trying to append values from a Member array to the one in the document. This is the function am currently using:

func (o *Organization) AddMembers (organizationID string, members []Member ) (*Organization, error){
    // if it doesn't exists it will be created
    collection := client.Database("app-data").Collection("organizations")

    log.Println("[APP-DATA-DB:ADD-MEMBERS] Requested new add members: ", members, organizationID)

    change := bson.M{
        "$push": bson.M {
            "members": bson.M{"$each": members},
        },
    }

    id, err := primitive.ObjectIDFromHex(organizationID)
    if err != nil{
        log.Println("[APP-DATA-DB:ADD-MEMBERS] cannot convert to primitive: ", id, organizationID)
        return nil, err
    }

    filter := bson.D{{"_id", id}}

    result, err := collection.UpdateOne(context.TODO(), filter, change)
    if err != nil {
        return nil, err
    }

    // get newly updated result
    updatedOrg, _ := o.GetOne(result.UpsertedID.(primitive.ObjectID).Hex())

    return updatedOrg, nil

}

From logs I've checked that both the ID and the input members array come in good format. However am getting into this error:

http: panic serving 172.23.0.4:42426: interface conversion: interface {} is nil, not primitive.ObjectID

I guess the error is coming in the way I define the update operation, however I haven't been able to find a solution for this.

Any help would be much appreciated, thanks in advance!


Solution

  • Looks like the error was coming from the upsertedID in *mongo.UpdateResult type. For some reason the id returned was nil.

    Changing

    // get newly updated result
        updatedOrg, _ := o.GetOne(result.UpsertedID.(primitive.ObjectID).Hex())
    

    for

    // get newly updated result
        updatedOrg, _ := o.GetOne(organizationID)
    

    did the trick.