在Go中使用MongoDb默认驱动程序创建唯一索引



我在使用官方的MongoDB Go驱动程序为我的一些数据创建唯一索引时遇到了一些问题。

所以我有一个这样的结构:

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"`
}

然后我想为name属性创建一个唯一的索引。我试着在我的Create函数(针对产品(中做这样的事情

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)
}

问题是,在创建产品之前,我不知道如何在上下文中传递indexModel作为选项。此外,我不确定我正在做的事情是否只创建了一次索引(这就是我想要做的(。如果能为我指明正确的方向,我将不胜感激。

我正在为Go使用echo框架,以防它提供更多上下文。

每次调用Create函数时,您的代码都会尝试创建索引,这会起作用,但效率不是很高,因为索引只需要创建一次(或者不存在(。我建议让建立数据库连接的函数负责创建索引,或者在初始化数据库连接后立即运行函数,这样它只运行一次(当程序启动时(。

由于collection.Indexes().CreateOne(...)方法在尝试创建已经存在的索引时不会返回错误,因此可以使用此方法来确保索引存在,类似于非官方MongoDB驱动程序具有EnsureIndex函数的方式。

或者,您可以按照Cahaba Data在回答中的建议,将索引创建作为一次性的数据库管理任务,而不是应用程序的责任。我之前曾与一些同事就此进行过讨论,虽然我确实同意从技术上讲,这是一项一次性的数据库管理任务,但我仍然希望我的应用程序在启动时确保它所需的索引确实存在,如果不存在,则创建索引。毕竟,如果有人忘记或创建了错误的索引,我的应用程序可能会出现故障/瘫痪。它还提供了关于应用程序需要/使用的索引的良好文档,而不必与DB管理员沟通,并希望他/她/它会适当地注意到这一点。当然,您可以自由形成自己的意见:(

是的,我认为创建索引是一个一次性的DBA/Admin事件。这不是应用程序/代码任务。使用适当权限登录mongo,创建索引,注销。。。。就是这样。除了mongoshell命令来创建索引之外,没有其他代码。

最新更新