imadu
imadu

Reputation: 99

Creating unique Indexes with MongoDb default driver in Go

I'm having some issues creating unique indexes for some of my data using the official MongoDB driver for Go.

So I have a struct like this:

type Product struct {
    ID        primitive.ObjectID `json:"_id" bson:"_id"`
    Name      string             `json:"name" bson:"name"`
    Price     float64            `json:"price" bson:"price"`
    Attribute []Attribute        `json:"attribute" bson:"attribute"`
    Category  string             `json:"category" bson:"category"`
}

And then I wan to create a unique index for the name property. I tried to do something like this in my Createfunction (for products)

func Create(c echo.Context) error {

    //unique index here 
    indexModel, err := productCollection.Indexes().CreateOne(context.Background(),
        IndexModel{
            Keys:    bsonx.Doc{{"name", bsonx.Int32(1)}},
            Options: options.Index().SetUnique(true),
        })
    if err != nil {
        log.Fatalf("something went wrong: %+v", err)
    }

    //create the product here
    p := new(Product)
    if err := c.Bind(p); err != nil {
        log.Fatalf("Could not bind request to struct: %+v", err)
        return util.SendError(c, "500", "something went wrong", "failed")
    }
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    result, _ := productCollection.InsertOne(ctx, p)

    return util.SendSuccess(c, result.InsertedID)

}

The problem is I don't exactly know how to pass indexModel as an option in the context before creating the product. Also, I'm not sure that with what I'm doing, I'm creating the index just once (which is what I want to do). I'd appreciate it if I could be pointed in the right direction on how to do this.

I'm using the echo framework for Go, just in case this provides more context.

Upvotes: 5

Views: 4752

Answers (2)

Bart van Oort
Bart van Oort

Reputation: 360

Your code will attempt to create the index every time the Create function is called, which will work, but is not very efficient, as an index only needs to be created once (or if it doesn't exist). I would recommend letting creation of your index be the responsibility of the function that sets up the connection to the DB, or a function run right after initialising the DB connection, such that it is run only once (when your program starts).

As the collection.Indexes().CreateOne(...) method doesn't return an error upon trying to create an index that already exists, you can use this as a way to ensure the index exists, similar to how the unofficial MongoDB driver had an EnsureIndex function.

Alternatively, you could do what Cahaba Data suggests in his answer, which is to make index creation be a one-time DB admin task instead of a responsibilty of your application. I've previously had discussions with some colleagues on this, and while I do agree that it technically is a one-time DB admin task, I still prefer to have my application ensure at startup that the indexes it needs are in fact there, creating them if they are not. After all, my application could malfunction / be crippled if someone forgets to or creates wrong indices. It also provides good documentation on which indices your application needs / uses, instead of having to communicate this with the DB admin and hoping that he / she / it will take proper note of it. Feel free to form your own opinion of course :)

Upvotes: 5

Cahaba Data
Cahaba Data

Reputation: 622

yes I kind of look at this in that creating an index is a 1-time DBA/Admin event. It's not an app/code task. log into mongo with appropriate permission, create index, log out....that's it. no code other then the mongo shell command to createIndex.

Upvotes: 0

Related Questions