MongoDB
MongoDB
Section titled “MongoDB”go-zero wraps the official mongo-driver with connection management and instrumentation.
Configuration
Section titled “Configuration”Mongo: Uri: "mongodb://127.0.0.1:27017" Database: myappAdd the struct to your config:
type Config struct { rest.RestConf Mongo struct { Uri string Database string }}Initialize
Section titled “Initialize”import "github.com/zeromicro/go-zero/core/stores/mongo"
func NewServiceContext(c config.Config) *ServiceContext { return &ServiceContext{ Config: c, ArticleMod: mongo.MustNewModel(c.Mongo.Uri, c.Mongo.Database, "articles"), }}Insert
Section titled “Insert”article := &Article{Title: "Hello go-zero", Content: "...", Published: false}result, err := l.svcCtx.ArticleMod.InsertOne(l.ctx, article)if err != nil { return nil, err}// result.InsertedID contains the new document's _idFind One
Section titled “Find One”var article Articleerr := l.svcCtx.ArticleMod.FindOne(l.ctx, bson.M{"_id": id}, &article)if errors.Is(err, mongo.ErrNotFound) { return nil, errorx.ErrNotFound}Find Many
Section titled “Find Many”var articles []Articleerr := l.svcCtx.ArticleMod.FindAll(l.ctx, bson.M{"published": true}, &articles)Limit and sort:
opts := options.Find().SetLimit(20).SetSort(bson.D{{Key: "createdAt", Value: -1}})err := l.svcCtx.ArticleMod.FindAllWithOptions(l.ctx, bson.M{}, &articles, opts)Update
Section titled “Update”Replace specific fields with $set:
filter := bson.M{"_id": id}update := bson.M{"$set": bson.M{"title": "Updated", "updatedAt": time.Now()}}result, err := l.svcCtx.ArticleMod.UpdateOne(l.ctx, filter, update)// result.MatchedCount / result.ModifiedCountUpsert (insert if not found):
opts := options.Update().SetUpsert(true)_, err = l.svcCtx.ArticleMod.UpdateOneWithOptions(l.ctx, filter, update, opts)Delete
Section titled “Delete”// Delete one documentresult, err := l.svcCtx.ArticleMod.DeleteOne(l.ctx, bson.M{"_id": id})
// Delete multiple documentsresult, err := l.svcCtx.ArticleMod.DeleteMany(l.ctx, bson.M{"published": false})// result.DeletedCountcount, err := l.svcCtx.ArticleMod.CountDocuments(l.ctx, bson.M{"published": true})Aggregation
Section titled “Aggregation”pipeline := mongo.Pipeline{ {{Key: "$match", Value: bson.M{"published": true}}}, {{Key: "$group", Value: bson.M{ "_id": "$authorId", "total": bson.M{"$sum": 1}, }}}, {{Key: "$sort", Value: bson.M{"total": -1}}}, {{Key: "$limit", Value: 10}},}
var results []bson.Merr := l.svcCtx.ArticleMod.Aggregate(l.ctx, pipeline, &results)Repository Pattern
Section titled “Repository Pattern”Wrap the model in a typed repository for cleaner logic code:
type ArticleModel interface { Insert(ctx context.Context, article *Article) error FindById(ctx context.Context, id primitive.ObjectID) (*Article, error) ListPublished(ctx context.Context, limit int64) ([]Article, error) Delete(ctx context.Context, id primitive.ObjectID) error}
type defaultArticleModel struct { mod *mongo.Model}
func NewArticleModel(uri, db string) ArticleModel { return &defaultArticleModel{mod: mongo.MustNewModel(uri, db, "articles")}}
func (m *defaultArticleModel) FindById(ctx context.Context, id primitive.ObjectID) (*Article, error) { var a Article if err := m.mod.FindOne(ctx, bson.M{"_id": id}, &a); err != nil { return nil, err } return &a, nil}