mongo 组件
基于 mongo-driver 管理多组 MongoDB 数据实例,配置方式与 gorm 组件 保持一致。
安装
bash
go get github.com/cherry-game/components/mongo@latest注册组件
go
import (
"github.com/cherry-game/cherry"
cherryMongo "github.com/cherry-game/components/mongo"
)
func main() {
app := cherry.Configure("./config/profile.json", "log-1", false, cherry.Standalone)
app.Register(cherryMongo.NewComponent())
app.Startup()
}配置
和 gorm 一样需要两处配合:mongo 段定义连接,节点 __settings__.mongo_id_list 声明要用哪些库。
json
{
"node": {
"game": [
{
"node_id": "game-1",
"__settings__": {
"mongo_id_list": {
"log_db_id": "log_db_1"
}
}
}
]
},
"mongo": {
"log_db_group": [
{
"enable": true,
"db_id": "log_db_1",
"db_name": "logs",
"uri": "mongodb://127.0.0.1:27017",
"timeout": 3
}
]
}
}mongo.<group>[n] 字段
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
db_id | string | — | 逻辑库 id,必填,与 mongo_id_list 的值匹配 |
enable | bool | true | 为 false 时跳过该连接 |
db_name | string | — | 库名 |
uri | string | — | 连接串,如 mongodb://127.0.0.1:27017 |
timeout | int | 3 | 超时秒数,只有大于 3 才生效 |
timeout 大于 3 才生效
实现里判断的是 timeout > 3秒,否则使用默认的 3 秒。也就是说填 1 或 3 都等于 3 秒,想调成 5 秒才需要显式配置。
日志已脱敏
连接日志只打印库名和主机列表,不会输出完整的 uri,避免把账号密码写进日志。
使用数据库
go
// 1. 取组件
mongoComponent, ok := app.Find(cherryMongo.Name).(*cherryMongo.Component)
if !ok || mongoComponent == nil {
clog.Panicf("[component = %s] not found.", cherryMongo.Name)
}
// 2. 读逻辑库 id
logDbID := app.Settings().GetConfig("mongo_id_list").GetString("log_db_id")
// 3. 取 *mongo.Database
db := mongoComponent.GetDb(logDbID)
// 4. 正常使用 mongo-driver
collection := db.Collection("player_log")新增或更新一条记录:
go
type Student struct {
ID int64 `bson:"id"`
Name string `bson:"name"`
}
collection := db.Collection("numbers")
// 建唯一索引
_, err := collection.Indexes().CreateOne(context.TODO(), mongo.IndexModel{
Keys: bson.D{{Key: "id", Value: 1}},
Options: options.Index().SetUnique(true),
})
// upsert
filter := bson.D{{Key: "id", Value: student.ID}}
update := bson.D{{Key: "$set", Value: student}}
_, err = collection.FindOneAndUpdate(context.TODO(), filter, update,
options.FindOneAndUpdate().SetUpsert(true),
)驱动是 v2
组件用的是 go.mongodb.org/mongo-driver/v2,import 路径带 /v2:
go
import (
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)从 v1 升级时注意:mongo.Connect(opts) 不再接收 ctx,且 primitive 系列类型已移除(应改用 bson 里的对应类型)。模型字段的 tag 仍然是 bson:"..."。
API
| 方法 | 说明 |
|---|---|
NewComponent() *Component | 创建组件 |
CreateDatabase(uri, dbName string, timeout ...time.Duration) (*mongo.Database, error) | 直接建连接,可脱离组件单独使用 |
GetDb(id string) *mongo.Database | 按逻辑库 id 取连接 |
GetHashDb(groupID string, hashFn HashDb) (*mongo.Database, bool) | 在一组库里按哈希规则选一个 |
GetDbMap(groupID string) (map[string]*mongo.Database, bool) | 取整组的连接表 |
CreateDatabase 是导出的,单元测试或临时脚本里可以直接用,不必注册组件:
go
mdb, err := cherryMongo.CreateDatabase("mongodb://localhost:27017", "test")
collection := mdb.Collection("numbers")可运行示例见 mongo_test.go。