Reputation: 99
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 Create
function (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
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
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