Skip to content

模型钩子(Model Hooks)

你可以针对模型(结构体)设置钩子函数,这些钩子函数会在 MongoDB 的集合操作前后被调用。例如,你可以在插入文档前后对文档进行处理,或者在查询文档后对文档进行处理。

目前支持的钩子函数有:

插入钩子(Insert Hook

  • 插入前的钩子(BeforeInsert
  • 插入后的钩子(AfterInsert

查询钩子(Find Hook

  • 查询后的钩子(AfterFind

保存钩子(Upsert Hook

  • 保存前的钩子(BeforeUpsert
  • 保存后的钩子(AfterUpsert

鉴于 MongoDB 的文档型数据库特性,以及某些操作不直接映射到结构体上,go mongox 不为删除和更新操作提供钩子函数。如果你有这方面的需求,你可以使用 go mongox 提供的 一次性钩子插件 功能来实现它们。

注意:只有在初始化插件时将 EnableModelHook 设置为 true(详情请参考 启用内置插件-钩子 )时,模型钩子才会生效。

插入钩子(Insert Hook

如果你想在插入文档的前后对文档进行处理,你可以实现以下特定的钩子方法:

go
BeforeInsert(ctx context.Context) error // 插入前的钩子
AfterInsert(ctx context.Context) error  // 插入后的钩子

代码示例:

go
type User struct {
	mongox.Model `bson:"inline"`
	Name         string `bson:"name"`
	Age          int    `bson:"age"`
}

func (u *User) BeforeInsert(ctx context.Context) error {
	fmt.Println("BeforeInsert called")
	return nil
}

func (u *User) AfterInsert(ctx context.Context) error {
	fmt.Println("AfterInsert called")
	return nil
}

_, err := userColl.Creator().InsertOne(context.Background(), u)

_, err = userColl.Creator().InsertMany(context.Background(), []*User{
    {Name: "Burt", Age: 18},
    {Name: "chenmingyong", Age: 18},
})

查询钩子(Find Hook

如果你想在查询文档后对文档进行处理,你可以实现以下特定的钩子方法:

go
AfterFind(ctx context.Context) error // 查询后的钩子

代码示例:

go
type User struct {
	mongox.Model `bson:"inline"`
	Name         string `bson:"name"`
	Age          int    `bson:"age"`
}

func (u *User) AfterFind(ctx context.Context) error {
	fmt.Println("AfterFind called")
	return nil
}
_, err := userColl.Finder().Filter(query.Eq("name", "Mingyong Chen")).FindOne(context.Background())

_, err = userColl.Finder().Filter(query.In("name", "Mingyong Chen", "Burt")).Find(context.Background())

保存钩子(Upsert Hook

如果你想在保存文档的前后对文档进行处理,你可以实现以下特定的钩子方法:

go
BeforeUpsert(ctx context.Context) error // 保存前的钩子
AfterUpsert(ctx context.Context) error  // 保存后的钩子

代码示例:

go
type User struct {
	mongox.Model `bson:"inline"`
	Name         string `bson:"name"`
	Age          int    `bson:"age"`
}

func (u *User) BeforeUpsert(ctx context.Context) error {
	fmt.Println("BeforeUpsert called")
	return nil
}

func (u *User) AfterUpsert(ctx context.Context) error {
	fmt.Println("AfterUpsert called")
	return nil
}

_, err := userColl.Updater().
		Filter(query.Eq("name", "Gopher")).
		Replacement(&User{Name: "Gopher", Age: 20}).
		Upsert(context.Background())