2

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

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

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 框架,以防万一这提供了更多上下文。

4

2 回答 2

0

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

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

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

于 2020-03-01T02:27:47.003 回答
0

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

于 2020-03-01T03:49:59.560 回答