ProductPromotion
Logo

Go.Lang

made by https://0x3d.site

GitHub - Kamva/mgm: Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)
Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver) - Kamva/mgm
Visit Site

GitHub - Kamva/mgm: Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)

GitHub - Kamva/mgm: Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)

Mongo Go Models

The Mongo ODM for Go

Features

  • Define your models and perform CRUD operations with hooks before/after each operation.
  • mgm makes Mongo search and aggregation super easy to do in Golang.
  • Just set up your configs once and get collections anywhere you need them.
  • mgm predefines all Mongo operators and keys, so you don't have to hardcode them yourself.
  • mgm wraps the official Mongo Go Driver.

Requirements

  • Go 1.17 or higher.
  • MongoDB 3.6 and higher.

Installation

go get github.com/kamva/mgm/v3

Usage

To get started, import the mgm package and setup the default config:

import (
   "github.com/kamva/mgm/v3"
   "go.mongodb.org/mongo-driver/mongo/options"
)

func init() {
   // Setup the mgm default config
   err := mgm.SetDefaultConfig(nil, "mgm_lab", options.Client().ApplyURI("mongodb://root:12345@localhost:27017"))
}

Define your model:

type Book struct {
   // DefaultModel adds _id, created_at and updated_at fields to the Model.
   mgm.DefaultModel `bson:",inline"`
   Name             string `json:"name" bson:"name"`
   Pages            int    `json:"pages" bson:"pages"`
}

func NewBook(name string, pages int) *Book {
   return &Book{
      Name:  name,
      Pages: pages,
   }
}

Insert new document:

book := NewBook("Pride and Prejudice", 345)

// Make sure to pass the model by reference (to update the model's "updated_at", "created_at" and "id" fields by mgm).
err := mgm.Coll(book).Create(book)

Find one document

// Get the document's collection
book := &Book{}
coll := mgm.Coll(book)

// Find and decode the doc to a book model.
_ = coll.FindByID("5e0518aa8f1a52b0b9410ee3", book)

// Get the first doc of the collection 
_ = coll.First(bson.M{}, book)

// Get the first doc of a collection using a filter
_ = coll.First(bson.M{"pages":400}, book)

Update a document

// Find your book
book := findMyFavoriteBook()

// and update it
book.Name = "Moulin Rouge!"
err := mgm.Coll(book).Update(book)

Delete a document

// Just find and delete your document
err := mgm.Coll(book).Delete(book)

Find and decode a result:

result := []Book{}

err := mgm.Coll(&Book{}).SimpleFind(&result, bson.M{"pages": bson.M{operator.Gt: 24}})

A Model's Default Fields

Each model by default (by using DefaultModel struct) has the following fields:

  • _id : The document ID.

  • created_at: The creation date of a doc. When saving a new doc, this is automatically populated by the Creating hook.

  • updated_at: The last updated date of a doc. When saving a doc, this is automatically populated by the Saving hook.

You can even implement your own default model to customize its fields.

A Model's Hooks

Each model has the following hooks:

  • Creating: Called when creating a new model. Signature : Creating(context.Context) error

  • Created: Called after a new model is created. Signature : Created(context.Context) error

  • Updating: Called when updating model. Signature : Updating(context.Context) error

  • Updated : Called after a model is updated. Signature : Updated(ctx context.Context, result *mongo.UpdateResult) error

  • Saving: Called when creating or updating a model. Signature : Saving(context.Context) error

  • Saved: Called after a model is created or updated. Signature: Saved(context.Context) error

  • Deleting: Called when deleting a model. Signature: Deleting(context.Context) error

  • Deleted: Called after a model is deleted. Signature: Deleted(ctx context.Context, result *mongo.DeleteResult) error

Notes about hooks:

  • Each model by default uses the Creating and Saving hooks, so if you want to define those hooks yourself, remember to invoke the DefaultModel hooks from your own hooks.
  • Collection methods that call these hooks:
    • Create & CreateWithCtx
    • Update & UpdateWithCtx
    • Delete & DeleteWithCtx

Example:

func (model *Book) Creating(ctx context.Context) error {
   // Call the DefaultModel Creating hook
   if err := model.DefaultModel.Creating(ctx); err!=nil {
      return err
   }

   // We can validate the fields of a model and return an error to prevent a document's insertion.
   if model.Pages < 1 {
      return errors.New("book must have at least one page")
   }

   return nil
}

Configuration

The mgm default configuration has a context timeout:

func init() {
   _ = mgm.SetDefaultConfig(&mgm.Config{CtxTimeout:12 * time.Second}, "mgm_lab", options.Client().ApplyURI("mongodb://root:12345@localhost:27017"))
}

// To get the context, just call the Ctx() method, assign it to a variable
ctx := mgm.Ctx()

// and use it
coll := mgm.Coll(&Book{})
coll.FindOne(ctx, bson.M{})

// Or invoke Ctx() and use it directly
coll.FindOne(mgm.Ctx(), bson.M{})

Collections

Get a model's collection:

coll := mgm.Coll(&Book{})

// Do something with the collection

mgm automatically detects the name of a model's collection:

book := Book{}

// Print your model's collection name.
collName := mgm.CollName(&book)
fmt.Println(collName) // output: books

You can also set a custom collection name for your model by implementing the CollectionNameGetter interface:

func (model *Book) CollectionName() string {
   return "my_books"
}

// mgm returns the "my_books" collection
coll := mgm.Coll(&Book{})

Get a collection by its name (without needing to define a model for it):

coll := mgm.CollectionByName("my_coll")
   
// Do Aggregation, etc. with the collection

Customize the model db by implementing the CollectionGetter interface:

func (model *Book) Collection() *mgm.Collection {
    // Get default connection client
   _, client, _, err := mgm.DefaultConfigs()

   if err != nil {
      panic(err)
   }

   db := client.Database("another_db")
   return mgm.NewCollection(db, "my_collection")
}

Or return a model's collection from another connection:

func (model *Book) Collection() *mgm.Collection {
   // Create new client
   client, err := mgm.NewClient(options.Client().ApplyURI("mongodb://root:12345@localhost:27017"))

   if err != nil {
      panic(err)
   }

   // Get the model's db
   db := client.Database("my_second_db")

   // return the model's custom collection
   return mgm.NewCollection(db, "my_collection")
}

Aggregation

While we can use Mongo Go Driver Aggregate features, mgm also provides simpler methods to perform aggregations:

Run an aggregation and decode the result:

authorCollName := mgm.Coll(&Author{}).Name()
result := []Book{}

// Lookup with just a single line of code
_ := mgm.Coll(&Book{}).SimpleAggregate(&result, builder.Lookup(authorCollName, "auth_id", "_id", "author"))

// Multi stage (mix of mgm builders and raw stages)
_ := mgm.Coll(&Book{}).SimpleAggregate(&result,
		builder.Lookup(authorCollName, "auth_id", "_id", "author"),
		M{operator.Project: M{"pages": 0}},
)

// Do something with result...

Do aggregations using the mongo Aggregation method:

import (
   "github.com/kamva/mgm/v3"
   "github.com/kamva/mgm/v3/builder"
   "github.com/kamva/mgm/v3/field"
   . "go.mongodb.org/mongo-driver/bson"
   "go.mongodb.org/mongo-driver/bson/primitive"
)

// The Author model collection
authorColl := mgm.Coll(&Author{})

cur, err := mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), A{
    // The S function accepts operators as parameters and returns a bson.M type.
    builder.S(builder.Lookup(authorColl.Name(), "author_id", field.Id, "author")),
})

A more complex example and mixes with mongo raw pipelines:

import (
   "github.com/kamva/mgm/v3"
   "github.com/kamva/mgm/v3/builder"
   "github.com/kamva/mgm/v3/field"
   "github.com/kamva/mgm/v3/operator"
   . "go.mongodb.org/mongo-driver/bson"
   "go.mongodb.org/mongo-driver/bson/primitive"
)

// Author model collection
authorColl := mgm.Coll(&Author{})

_, err := mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), A{
    // S function get operators and return bson.M type.
    builder.S(builder.Lookup(authorColl.Name(), "author_id", field.Id, "author")),
    builder.S(builder.Group("pages", M{"books": M{operator.Push: M{"name": "$name", "author": "$author"}}})),
    M{operator.Unwind: "$books"},
})

if err != nil {
    panic(err)
}

Transactions

  • To run a transaction on the default connection use the mgm.Transaction() function, e.g:
d := &Doc{Name: "Mehran", Age: 10}

err := mgm.Transaction(func(session mongo.Session, sc mongo.SessionContext) error {

   // do not forget to pass the session's context to the collection methods.
	err := mgm.Coll(d).CreateWithCtx(sc, d)

	if err != nil {
		return err
	}

	return session.CommitTransaction(sc)
})
  • To run a transaction with your own context, use the mgm.TransactionWithCtx() method.
  • To run a transaction on another connection, use the mgm.TransactionWithClient() method.

Other Mongo Go Models Packages

We implemented these packages to simplify queries and aggregations in mongo

builder: simplify mongo queries and aggregations.

operator : contains mongo operators as predefined variables.
(e.g Eq = "$eq" , Gt = "$gt")

field : contains mongo fields used in aggregations and ... as predefined variable. (e.g LocalField = "localField", ForeignField = "foreignField")

Example:

import (
  "github.com/kamva/mgm/v3"
  f "github.com/kamva/mgm/v3/field"
  o "github.com/kamva/mgm/v3/operator"
  "go.mongodb.org/mongo-driver/bson"
)

// Instead of hard-coding mongo operators and fields
_, _ = mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), bson.A{
   bson.M{"$count": ""},
   bson.M{"$project": bson.M{"_id": 0}},
})

// Use the predefined operators and pipeline fields.
_, _ = mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), bson.A{
   bson.M{o.Count: ""},
   bson.M{o.Project: bson.M{f.Id: 0}},
})

Bugs / Feature request

New features can be requested and bugs can be reported on Github issue tracker.

Communicate With Us

Contributing

Open in Gitpod FOSSA Status

  1. Fork the repository
  2. Clone your fork (git clone https://github.com/<your_username>/mgm && cd mgm)
  3. Create your feature branch (git checkout -b my-new-feature)
  4. Make changes and add them (git add .)
  5. Commit your changes (git commit -m 'Add some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create new pull request

License

Mongo Go Models is released under the Apache License

FOSSA Status

Articles
to learn more about the golang concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here ๐Ÿ”ฅ.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here ๐Ÿ”ฅ.

Queries
or most google FAQ's about GoLang.

mail [email protected] to add more queries here ๐Ÿ”.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory