在 Go 中使用 MongoDb 默认驱动程序创建唯一索引
Creating unique Indexes with MongoDb default driver in Go
我在使用 official MongoDB driver for 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(...)
方法在尝试创建已存在的索引时不会 return 出错,因此您可以使用此方法来确保索引存在,类似于非官方 MongoDB 驱动程序具有 EnsureIndex
功能。
或者,您可以按照 Cahaba Data 在 中的建议进行操作,即让索引创建成为一次性的数据库管理任务,而不是您的应用程序的职责。我以前曾与一些同事讨论过这个问题,虽然我同意从技术上讲它是一次性的数据库管理任务,但我仍然更喜欢让我的应用程序在启动时确保它需要的索引确实存在,创建他们,如果他们不是。毕竟,如果有人忘记或创建错误的索引,我的应用程序可能会出现故障/瘫痪。它还提供了关于您的应用程序需要/使用哪些索引的良好文档,而不是必须与数据库管理员沟通并希望他/她/它会适当注意它。当然,请随意形成您自己的意见:)
是的,我认为创建索引是 1 次 DBA/Admin 事件。这不是 app/code 任务。以适当的权限登录 mongo,创建索引,注销……就是这样。除了 createIndex 的 mongo shell 命令之外没有其他代码。
我在使用 official MongoDB driver for 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(...)
方法在尝试创建已存在的索引时不会 return 出错,因此您可以使用此方法来确保索引存在,类似于非官方 MongoDB 驱动程序具有 EnsureIndex
功能。
或者,您可以按照 Cahaba Data 在
是的,我认为创建索引是 1 次 DBA/Admin 事件。这不是 app/code 任务。以适当的权限登录 mongo,创建索引,注销……就是这样。除了 createIndex 的 mongo shell 命令之外没有其他代码。