qmgo

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2022 License: Apache-2.0 Imports: 20 Imported by: 0

README

Qmgo

Build Status Coverage Status [![Go Report Card](https://goreportcard.com/badge/git hub.com/leimeng-go/qmgo)](https://goreportcard.com/report/git hub.com/leimeng-go/qmgo) GitHub release [![GoDoc](https://pkg.go.dev/badge/git hub.com/leimeng-go/qmgo?status.svg)](https://pkg.go.dev/git hub.com/leimeng-go/qmgo?tab=doc)

English | 简体中文

Qmgo is a Go driver for MongoDB . It is based on MongoDB official driver, but easier to use like mgo (such as the chain call).

  • Qmgo allows users to use the new features of MongoDB in a more elegant way.

  • Qmgo is the first choice for migrating from mgo to the new MongoDB driver with minimal code changes.

Requirements

-Go 1.10 and above.

-MongoDB 2.6 and above.

Features

  • CRUD to documents, with all official supported options
  • Sort、limit、count、select、distinct
  • Transactions
  • Hooks
  • Automatically default and custom fields
  • Predefine operator keys
  • Aggregate、indexes operation、cursor
  • Validation tags
  • Plugin

Installation

  • Use go mod to automatically install dependencies by import git hub.com/leimeng-go/qmgo

Or

  • Use go get git hub.com/leimeng-go/qmgo

Usage

  • Start

    import and create a new connection

    import (
        "context"
    
        "git hub.com/leimeng-go/qmgo"
    )
    
    ctx := context.Background()
    client, err := qmgo.NewClient(ctx, &qmgo.Config{Uri: "mongodb://localhost:27017"})
    db := client.Database("class")
    coll := db.Collection("user")
    

    If your connection points to a fixed database and collection, recommend using the following way to initialize the connection. All operations can be based on cli:

    cli, err := qmgo.Open(ctx, &qmgo.Config{Uri: "mongodb://localhost:27017", Database: "class", Coll: "user"})
    

    The following examples will be based on cli, if you use the first way for initialization, replace cli with clientdb or coll

    Make sure to defer a call to Disconnect after instantiating your client:

    defer func() {
    if err = cli.Close(ctx); err != nil {
            panic(err)
        }
    }()
    
  • Create index

    Before doing the operation, we first initialize some data:

    type UserInfo struct {
        Name   string `bson:"name"`
        Age    uint16 `bson:"age"`
        Weight uint32 `bson:"weight"`
    }
    
    var userInfo = UserInfo{
        Name: "xm",
        Age: 7,
        Weight: 40,
    }
    

    Create index

    cli.CreateOneIndex(context.Background(), options.IndexModel{Key: []string{"name"}, Unique: true})
    cli.CreateIndexes(context.Background(), []options.IndexModel{{Key: []string{"id2", "id3"}}})
    
  • Insert a document

    // insert one document
    result, err := cli.InsertOne(ctx, userInfo)
    
  • Find a document

    // find one document
      one := UserInfo{}
      err = cli.Find(ctx, bson.M{"name": userInfo.Name}).One(&one)
    
  • Delete documents

    err = cli.Remove(ctx, bson.M{"age": 7})
    
  • Insert multiple data

    // multiple insert
    var userInfos = []UserInfo{
        UserInfo{Name: "a1", Age: 6, Weight: 20},
        UserInfo{Name: "b2", Age: 6, Weight: 25},
        UserInfo{Name: "c3", Age: 6, Weight: 30},
        UserInfo{Name: "d4", Age: 6, Weight: 35},
        UserInfo{Name: "a1", Age: 7, Weight: 40},
        UserInfo{Name: "a1", Age: 8, Weight: 45},
    }
    result, err = cli.Collection.InsertMany(ctx, userInfos)
    
  • Search all, sort and limit

    // find all, sort and limit
    batch := []UserInfo{}
    cli.Find(ctx, bson.M{"age": 6}).Sort("weight").Limit(7).All(&batch)
    
  • Count

    count, err := cli.Find(ctx, bson.M{"age": 6}).Count()
    
  • Update

    // UpdateOne one
    err := cli.UpdateOne(ctx, bson.M{"name": "d4"}, bson.M{"$set": bson.M{"age": 7}})
    
    // UpdateAll
    result, err := cli.UpdateAll(ctx, bson.M{"age": 6}, bson.M{"$set": bson.M{"age": 10}})
    
  • Select

    err := cli.Find(ctx, bson.M{"age": 10}).Select(bson.M{"age": 1}).One(&one)
    
  • Aggregate

    matchStage := bson.D{{"$match", []bson.E{{"weight", bson.D{{"$gt", 30}}}}}}
    groupStage := bson.D{{"$group", bson.D{{"_id", "$name"}, {"total", bson.D{{"$sum", "$age"}}}}}}
    var showsWithInfo []bson.M
    err = cli.Aggregate(context.Background(), Pipeline{matchStage, groupStage}).All(&showsWithInfo)
    
  • Support All mongoDB Options when create connection

    poolMonitor := &event.PoolMonitor{
        Event: func(evt *event.PoolEvent) {
            switch evt.Type {
            case event.GetSucceeded:
                fmt.Println("GetSucceeded")
            case event.ConnectionReturned:
                fmt.Println("ConnectionReturned")
            }
        },
    }
    opt := options.Client().SetPoolMonitor(poolMonitor)  // more options use the chain options.
    cli, err := Open(ctx, &Config{Uri: URI, Database: DATABASE, Coll: COLL}, opt) 
    
    
    
  • Transactions

    The super simple and powerful transaction, with features like timeoutretry:

    callback := func(sessCtx context.Context) (interface{}, error) {
        // Important: make sure the sessCtx used in every operation in the whole transaction
        if _, err := cli.InsertOne(sessCtx, bson.D{{"abc", int32(1)}}); err != nil {
            return nil, err
        }
        if _, err := cli.InsertOne(sessCtx, bson.D{{"xyz", int32(999)}}); err != nil {
            return nil, err
        }
        return nil, nil
    }
    result, err = cli.DoTransaction(ctx, callback)
    

    More about transaction

  • Predefine operator keys

    // aggregate
    matchStage := bson.D{{operator.Match, []bson.E{{"weight", bson.D{{operator.Gt, 30}}}}}}
    groupStage := bson.D{{operator.Group, bson.D{{"_id", "$name"}, {"total", bson.D{{operator.Sum, "$age"}}}}}}
    var showsWithInfo []bson.M
    err = cli.Aggregate(context.Background(), Pipeline{matchStage, groupStage}).All(&showsWithInfo)
    
  • Hooks

    Qmgo flexible hooks:

    type User struct {
        Name         string    `bson:"name"`
        Age          int       `bson:"age"`
    }
    func (u *User) BeforeInsert() error {
        fmt.Println("before insert called")
        return nil
    }
    func (u *User) AfterInsert() error {
        fmt.Println("after insert called")
        return nil
    }
    
    u := &User{Name: "Alice", Age: 7}
    _, err := cli.InsertOne(context.Background(), u)
    

    More about hooks

  • Automatically fields

    Qmgo support two ways to make specific fields automatically update in specific API

    • Default fields

    Inject field.DefaultField in document struct, Qmgo will update createAtupdateAt and _id in update and insert operation.

    type User struct {
      field.DefaultField `bson:",inline"`
    
      Name string `bson:"name"`
      Age  int    `bson:"age"`
    }
    
    u := &User{Name: "Lucas", Age: 7}
    _, err := cli.InsertOne(context.Background(), u)
    // Fields with tag createAt、updateAt and _id will be generated automatically 
    
    • Custom fields

    Define the custom fields, Qmgo will update them in update and insert operation.

    type User struct {
        Name string `bson:"name"`
        Age  int    `bson:"age"`
    
        MyId         string    `bson:"myId"`
        CreateTimeAt time.Time `bson:"createTimeAt"`
        UpdateTimeAt int64     `bson:"updateTimeAt"`
    }
    // Define the custom fields
    func (u *User) CustomFields() field.CustomFieldsBuilder {
        return field.NewCustom().SetCreateAt("CreateTimeAt").SetUpdateAt("UpdateTimeAt").SetId("MyId")
    }
    
    u := &User{Name: "Lucas", Age: 7}
    _, err := cli.InsertOne(context.Background(), u)
    // CreateTimeAt、UpdateTimeAt and MyId will be generated automatically 
    
    // suppose Id and ui is ready
    err = cli.ReplaceOne(context.Background(), bson.M{"_id": Id}, &ui)
    // UpdateTimeAt will update
    

    Check examples here

    More about automatically fields

  • Validation tags

    Qmgo Validation tags is Based on go-playground/validator.

    So Qmgo support all validations on structs in go-playground/validator, such as:

    type User struct {
        FirstName string            `bson:"fname"`
        LastName  string            `bson:"lname"`
        Age       uint8             `bson:"age" validate:"gte=0,lte=130" `    // Age must in [0,130]
        Email     string            `bson:"e-mail" validate:"required,email"` //  Email can't be empty string, and must has email format
        CreateAt  time.Time         `bson:"createAt" validate:"lte"`          // CreateAt must lte than current time
        Relations map[string]string `bson:"relations" validate:"max=2"`       // Relations can't has more than 2 elements
    }
    

    Qmgo tags only supported in following API: InsertOne、InsertyMany、Upsert、UpsertId、ReplaceOne

  • Plugin

    • Implement following method:
    func Do(doc interface{}, opType operator.OpType, opts ...interface{}) error{
      // do anything
    }
    
    • Call Register() in package middleware, register the method Do

      Qmgo will call Do before and after the operation

    middleware.Register(Do)
    

    Example

    The hookautomatically fields and validation tags in Qmgo run on plugin.

Qmgo vs go.mongodb.org/mongo-driver

Below we give an example of multi-file search、sort and limit to illustrate the similarities between qmgo and mgo and the improvement compare to go.mongodb.org/mongo-driver. How do we do ingo.mongodb.org/mongo-driver:

// go.mongodb.org/mongo-driver
// find all, sort and limit
findOptions := options.Find()
findOptions.SetLimit(7) // set limit
var sorts D
sorts = append(sorts, E{Key: "weight", Value: 1})
findOptions.SetSort(sorts) // set sort

batch := []UserInfo{}
cur, err := coll.Find(ctx, bson.M{"age": 6}, findOptions)
cur.All(ctx, &batch)

How do we do in Qmgo and mgo:

// qmgo
// find all, sort and limit
batch := []UserInfo{}
cli.Find(ctx, bson.M{"age": 6}).Sort("weight").Limit(7).All(&batch)

// mgo
// find all, sort and limit
coll.Find(bson.M{"age": 6}).Sort("weight").Limit(7).All(&batch)

Qmgo vs mgo

Differences between qmgo and mgo

Contributing

The Qmgo project welcomes all contributors. We appreciate your help!

Communication:

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrQueryNotSlicePointer return if result argument is not a pointer to a slice
	ErrQueryNotSlicePointer = errors.New("result argument must be a pointer to a slice")
	// ErrQueryNotSliceType return if result argument is not slice address
	ErrQueryNotSliceType = errors.New("result argument must be a slice address")
	// ErrQueryResultTypeInconsistent return if result type is not equal mongodb value type
	ErrQueryResultTypeInconsistent = errors.New("result type is not equal mongodb value type")
	// ErrQueryResultValCanNotChange return if the value of result can not be changed
	ErrQueryResultValCanNotChange = errors.New("the value of result can not be changed")
	// ErrNoSuchDocuments return if no document found
	ErrNoSuchDocuments = mongo.ErrNoDocuments
	// ErrTransactionRetry return if transaction need to retry
	ErrTransactionRetry = errors.New("retry transaction")
	// ErrTransactionNotSupported return if transaction not supported
	ErrTransactionNotSupported = errors.New("transaction not supported")
	// ErrNotSupportedUsername return if username is invalid
	ErrNotSupportedUsername = errors.New("username not supported")
	// ErrNotSupportedPassword return if password is invalid
	ErrNotSupportedPassword = errors.New("password not supported")
	// ErrNotValidSliceToInsert return if insert argument is not valid slice
	ErrNotValidSliceToInsert = errors.New("must be valid slice to insert")
	// ErrReplacementContainUpdateOperators return if replacement document contain update operators
	ErrReplacementContainUpdateOperators = errors.New("replacement document cannot contain keys beginning with '$'")
)

Functions

func CompareVersions

func CompareVersions(v1 string, v2 string) (int, error)

CompareVersions compares two version number strings (i.e. positive integers separated by periods). Comparisons are done to the lesser precision of the two versions. For example, 3.2 is considered equal to 3.2.11, whereas 3.2.0 is considered less than 3.2.11.

Returns a positive int if version1 is greater than version2, a negative int if version1 is less than version2, and 0 if version1 is equal to version2.

func IsDup

func IsDup(err error) bool

IsDup check if err is mongo E11000 (duplicate err)。

func IsErrNoDocuments

func IsErrNoDocuments(err error) bool

IsErrNoDocuments check if err is no documents, both mongo-go-driver error and qmgo custom error Deprecated, simply call if err == ErrNoSuchDocuments or if err == mongo.ErrNoDocuments

func NewObjectID

func NewObjectID() primitive.ObjectID

NewObjectID generates a new ObjectID. Watch out: the way it generates objectID is different from mgo

func Now

func Now() time.Time

Now return Millisecond current time

func SplitSortField

func SplitSortField(field string) (key string, sort int32)

SplitSortField handle sort symbol: "+"/"-" in front of field if "+", return sort as 1 if "-", return sort as -1

Types

type Aggregate

type Aggregate struct {
	// contains filtered or unexported fields
}

Aggregate is a handle to a aggregate

func (*Aggregate) All

func (a *Aggregate) All(results interface{}) error

All iterates the cursor from aggregate and decodes each document into results.

func (*Aggregate) Iter

func (a *Aggregate) Iter() CursorI

Iter return the cursor after aggregate

func (*Aggregate) One

func (a *Aggregate) One(result interface{}) error

One iterates the cursor from aggregate and decodes current document into result.

type AggregateI

type AggregateI interface {
	All(results interface{}) error
	One(result interface{}) error
	Iter() CursorI
}

AggregateI define the interface of aggregate

type Bulk

type Bulk struct {
	// contains filtered or unexported fields
}

Bulk is context for batching operations to be sent to database in a single bulk write.

Bulk is not safe for concurrent use.

Notes:

Individual operations inside a bulk do not trigger middlewares or hooks at present.

Different from original mgo, the qmgo implementation of Bulk does not emulate bulk operations individually on old versions of MongoDB servers that do not natively support bulk operations.

Only operations supported by the official driver are exposed, that is why InsertMany is missing from the methods.

func (*Bulk) InsertOne

func (b *Bulk) InsertOne(doc interface{}) *Bulk

InsertOne queues an InsertOne operation for bulk execution.

func (*Bulk) Remove

func (b *Bulk) Remove(filter interface{}) *Bulk

Remove queues a Remove operation for bulk execution.

func (*Bulk) RemoveAll

func (b *Bulk) RemoveAll(filter interface{}) *Bulk

RemoveAll queues a RemoveAll operation for bulk execution.

func (*Bulk) RemoveId

func (b *Bulk) RemoveId(id interface{}) *Bulk

RemoveId queues a RemoveId operation for bulk execution.

func (*Bulk) Run

func (b *Bulk) Run(ctx context.Context) (*BulkResult, error)

Run executes the collected operations in a single bulk operation.

A successful call resets the Bulk. If an error is returned, the internal queue of operations is unchanged, containing both successful and failed operations.

func (*Bulk) SetOrdered

func (b *Bulk) SetOrdered(ordered bool) *Bulk

SetOrdered marks the bulk as ordered or unordered.

If ordered, writes does not continue after one individual write fails. Default is ordered.

func (*Bulk) UpdateAll

func (b *Bulk) UpdateAll(filter interface{}, update interface{}) *Bulk

UpdateAll queues an UpdateAll operation for bulk execution. The update should contain operator

func (*Bulk) UpdateId

func (b *Bulk) UpdateId(id interface{}, update interface{}) *Bulk

UpdateId queues an UpdateId operation for bulk execution. The update should contain operator

func (*Bulk) UpdateOne

func (b *Bulk) UpdateOne(filter interface{}, update interface{}) *Bulk

UpdateOne queues an UpdateOne operation for bulk execution. The update should contain operator

func (*Bulk) Upsert

func (b *Bulk) Upsert(filter interface{}, replacement interface{}) *Bulk

Upsert queues an Upsert operation for bulk execution. The replacement should be document without operator

func (*Bulk) UpsertId

func (b *Bulk) UpsertId(id interface{}, replacement interface{}) *Bulk

UpsertId queues an UpsertId operation for bulk execution. The replacement should be document without operator

type BulkResult

type BulkResult struct {
	// The number of documents inserted.
	InsertedCount int64

	// The number of documents matched by filters in update and replace operations.
	MatchedCount int64

	// The number of documents modified by update and replace operations.
	ModifiedCount int64

	// The number of documents deleted.
	DeletedCount int64

	// The number of documents upserted by update and replace operations.
	UpsertedCount int64

	// A map of operation index to the _id of each upserted document.
	UpsertedIDs map[int64]interface{}
}

BulkResult is the result type returned by Bulk.Run operation.

type Change

type Change struct {
	Update    interface{} // update/replace document
	Replace   bool        // Whether to replace the document rather than updating
	Remove    bool        // Whether to remove the document found rather than updating
	Upsert    bool        // Whether to insert in case the document isn't found, take effect when Remove is false
	ReturnNew bool        // Should the modified document be returned rather than the old one, take effect when Remove is false
}

Change holds fields for running a findAndModify command via the Query.Apply method.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client creates client to mongo

func NewClient

func NewClient(ctx context.Context, conf *Config, o ...options.ClientOptions) (cli *Client, err error)

NewClient creates Qmgo MongoDB client

func (*Client) Close

func (c *Client) Close(ctx context.Context) error

Close closes sockets to the topology referenced by this Client.

func (*Client) Database

func (c *Client) Database(name string) *Database

Database create connection to database

func (*Client) DoTransaction

func (c *Client) DoTransaction(ctx context.Context, callback func(sessCtx context.Context) (interface{}, error)) (interface{}, error)

DoTransaction do whole transaction in one function precondition: - version of mongoDB server >= v4.0 - Topology of mongoDB server is not Single At the same time, please pay attention to the following

  • make sure all operations in callback use the sessCtx as context parameter
  • if operations in callback takes more than(include equal) 120s, the operations will not take effect,
  • if operation in callback return qmgo.ErrTransactionRetry, the whole transaction will retry, so this transaction must be idempotent
  • if operations in callback return qmgo.ErrTransactionNotSupported,
  • If the ctx parameter already has a Session attached to it, it will be replaced by this session.

func (*Client) Ping

func (c *Client) Ping(timeout int64) error

Ping confirm connection is alive

func (*Client) ServerVersion

func (c *Client) ServerVersion() string

ServerVersion get the version of mongoDB server, like 4.4.0

func (*Client) Session

func (c *Client) Session() (*Session, error)

Session create one session on client Watch out, close session after operation done

type Collection

type Collection struct {
	// contains filtered or unexported fields
}

Collection is a handle to a MongoDB collection

func (*Collection) Aggregate

func (c *Collection) Aggregate(ctx context.Context, pipeline interface{}, opts ...opts.AggregateOptions) AggregateI

Aggregate executes an aggregate command against the collection and returns a AggregateI to get resulting documents.

func (*Collection) Bulk

func (c *Collection) Bulk() *Bulk

Bulk returns a new context for preparing bulk execution of operations.

func (*Collection) CloneCollection

func (c *Collection) CloneCollection() (*mongo.Collection, error)

CloneCollection creates a copy of the Collection

func (*Collection) CreateIndexes

func (c *Collection) CreateIndexes(ctx context.Context, indexes []opts.IndexModel) (err error)

CreateIndexes creates multiple indexes in collection If the Key in opts.IndexModel is []string{"name"}, means create index: name If the Key in opts.IndexModel is []string{"name","-age"} means create Compound indexes: name and -age

func (*Collection) CreateOneIndex

func (c *Collection) CreateOneIndex(ctx context.Context, index opts.IndexModel) error

CreateOneIndex creates one index If the Key in opts.IndexModel is []string{"name"}, means create index name If the Key in opts.IndexModel is []string{"name","-age"} means create Compound index: name and -age

func (*Collection) DropAllIndexes

func (c *Collection) DropAllIndexes(ctx context.Context) (err error)

DropAllIndexes drop all indexes on the collection except the index on the _id field if there is only _id field index on the collection, the function call will report an error

func (*Collection) DropCollection

func (c *Collection) DropCollection(ctx context.Context) error

DropCollection drops collection it's safe even collection is not exists

func (*Collection) DropIndex

func (c *Collection) DropIndex(ctx context.Context, indexes []string) error

DropIndex drop indexes in collection, indexes that be dropped should be in line with inputting indexes The indexes is []string{"name"} means drop index: name The indexes is []string{"name","-age"} means drop Compound indexes: name and -age

func (*Collection) EnsureIndexes

func (c *Collection) EnsureIndexes(ctx context.Context, uniques []string, indexes []string) (err error)

EnsureIndexes Deprecated Recommend to use CreateIndexes / CreateOneIndex for more function) EnsureIndexes creates unique and non-unique indexes in collection the combination of indexes is different from CreateIndexes: if uniques/indexes is []string{"name"}, means create index "name" if uniques/indexes is []string{"name,-age","uid"} means create Compound indexes: name and -age, then create one index: uid

func (*Collection) Find

func (c *Collection) Find(ctx context.Context, filter interface{}, opts ...opts.FindOptions) QueryI

Find find by condition filter,return QueryI

func (*Collection) GetCollectionName

func (c *Collection) GetCollectionName() string

GetCollectionName returns the name of collection

func (*Collection) InsertMany

func (c *Collection) InsertMany(ctx context.Context, docs interface{}, opts ...opts.InsertManyOptions) (result *InsertManyResult, err error)

InsertMany executes an insert command to insert multiple documents into the collection. If InsertHook in opts is set, hook works on it, otherwise hook try the doc as hook Reference: https://docs.mongodb.com/manual/reference/command/insert/

func (*Collection) InsertOne

func (c *Collection) InsertOne(ctx context.Context, doc interface{}, opts ...opts.InsertOneOptions) (result *InsertOneResult, err error)

InsertOne insert one document into the collection If InsertHook in opts is set, hook works on it, otherwise hook try the doc as hook Reference: https://docs.mongodb.com/manual/reference/command/insert/

func (*Collection) Remove

func (c *Collection) Remove(ctx context.Context, filter interface{}, opts ...opts.RemoveOptions) (err error)

Remove executes a delete command to delete at most one document from the collection. if filter is bson.M{},DeleteOne will delete one document in collection Reference: https://docs.mongodb.com/manual/reference/command/delete/

func (*Collection) RemoveAll

func (c *Collection) RemoveAll(ctx context.Context, filter interface{}, opts ...opts.RemoveOptions) (result *DeleteResult, err error)

RemoveAll executes a delete command to delete documents from the collection. If filter is bson.M{},all ducuments in Collection will be deleted Reference: https://docs.mongodb.com/manual/reference/command/delete/

func (*Collection) RemoveId

func (c *Collection) RemoveId(ctx context.Context, id interface{}, opts ...opts.RemoveOptions) (err error)

RemoveId executes a delete command to delete at most one document from the collection.

func (*Collection) ReplaceOne

func (c *Collection) ReplaceOne(ctx context.Context, filter interface{}, doc interface{}, opts ...opts.ReplaceOptions) (err error)

ReplaceOne executes an update command to update at most one document in the collection. If UpdateHook in opts is set, hook works on it, otherwise hook try the doc as hook Expect type of the doc is the define of user's document

func (*Collection) UpdateAll

func (c *Collection) UpdateAll(ctx context.Context, filter interface{}, update interface{}, opts ...opts.UpdateOptions) (result *UpdateResult, err error)

UpdateAll executes an update command to update documents in the collection. The matchedCount is 0 in UpdateResult if no document updated Reference: https://docs.mongodb.com/manual/reference/operator/update/

func (*Collection) UpdateId

func (c *Collection) UpdateId(ctx context.Context, id interface{}, update interface{}, opts ...opts.UpdateOptions) (err error)

UpdateId executes an update command to update at most one document in the collection. Reference: https://docs.mongodb.com/manual/reference/operator/update/

func (*Collection) UpdateOne

func (c *Collection) UpdateOne(ctx context.Context, filter interface{}, update interface{}, opts ...opts.UpdateOptions) (err error)

UpdateOne executes an update command to update at most one document in the collection. Reference: https://docs.mongodb.com/manual/reference/operator/update/

func (*Collection) Upsert

func (c *Collection) Upsert(ctx context.Context, filter interface{}, replacement interface{}, opts ...opts.UpsertOptions) (result *UpdateResult, err error)

Upsert updates one documents if filter match, inserts one document if filter is not match, Error when the filter is invalid The replacement parameter must be a document that will be used to replace the selected document. It cannot be nil and cannot contain any update operators Reference: https://docs.mongodb.com/manual/reference/operator/update/ If replacement has "_id" field and the document is exist, please initial it with existing id(even with Qmgo default field feature). Otherwise "the (immutable) field '_id' altered" error happens.

func (*Collection) UpsertId

func (c *Collection) UpsertId(ctx context.Context, id interface{}, replacement interface{}, opts ...opts.UpsertOptions) (result *UpdateResult, err error)

UpsertId updates one documents if id match, inserts one document if id is not match and the id will inject into the document The replacement parameter must be a document that will be used to replace the selected document. It cannot be nil and cannot contain any update operators Reference: https://docs.mongodb.com/manual/reference/operator/update/

type Config

type Config struct {
	// URI example: [mongodb://][user:pass@]host1[:port1][,host2[:port2],...][/database][?options]
	// URI Reference: https://docs.mongodb.com/manual/reference/connection-string/
	Uri      string `json:"uri"`
	Database string `json:"database"`
	Coll     string `json:"coll"`
	// ConnectTimeoutMS specifies a timeout that is used for creating connections to the server.
	//	If set to 0, no timeout will be used.
	//	The default is 30 seconds.
	ConnectTimeoutMS *int64 `json:"connectTimeoutMS"`
	// MaxPoolSize specifies that maximum number of connections allowed in the driver's connection pool to each server.
	// If this is 0, it will be set to math.MaxInt64,
	// The default is 100.
	MaxPoolSize *uint64 `json:"maxPoolSize"`
	// MinPoolSize specifies the minimum number of connections allowed in the driver's connection pool to each server. If
	// this is non-zero, each server's pool will be maintained in the background to ensure that the size does not fall below
	// the minimum. This can also be set through the "minPoolSize" URI option (e.g. "minPoolSize=100"). The default is 0.
	MinPoolSize *uint64 `json:"minPoolSize"`
	// SocketTimeoutMS specifies how long the driver will wait for a socket read or write to return before returning a
	// network error. If this is 0 meaning no timeout is used and socket operations can block indefinitely.
	// The default is 300,000 ms.
	SocketTimeoutMS *int64 `json:"socketTimeoutMS"`
	// ReadPreference determines which servers are considered suitable for read operations.
	// default is PrimaryMode
	ReadPreference *ReadPref `json:"readPreference"`
	// can be used to provide authentication options when configuring a Client.
	Auth *Credential `json:"auth"`
}

Config for initial mongodb instance

type Credential

type Credential struct {
	AuthMechanism string `json:"authMechanism"`
	AuthSource    string `json:"authSource"`
	Username      string `json:"username"`
	Password      string `json:"password"`
	PasswordSet   bool   `json:"passwordSet"`
}

Credential can be used to provide authentication options when configuring a Client.

AuthMechanism: the mechanism to use for authentication. Supported values include "SCRAM-SHA-256", "SCRAM-SHA-1", "MONGODB-CR", "PLAIN", "GSSAPI", "MONGODB-X509", and "MONGODB-AWS". This can also be set through the "authMechanism" URI option. (e.g. "authMechanism=PLAIN"). For more information, see https://docs.mongodb.com/manual/core/authentication-mechanisms/. AuthSource: the name of the database to use for authentication. This defaults to "$external" for MONGODB-X509, GSSAPI, and PLAIN and "admin" for all other mechanisms. This can also be set through the "authSource" URI option (e.g. "authSource=otherDb").

Username: the username for authentication. This can also be set through the URI as a username:password pair before the first @ character. For example, a URI for user "user", password "pwd", and host "localhost:27017" would be "mongodb://user:pwd@localhost:27017". This is optional for X509 authentication and will be extracted from the client certificate if not specified.

Password: the password for authentication. This must not be specified for X509 and is optional for GSSAPI authentication.

PasswordSet: For GSSAPI, this must be true if a password is specified, even if the password is the empty string, and false if no password is specified, indicating that the password should be taken from the context of the running process. For other mechanisms, this field is ignored.

type Cursor

type Cursor struct {
	// contains filtered or unexported fields
}

Cursor struct define

func (*Cursor) All

func (c *Cursor) All(results interface{}) error

All iterates the cursor and decodes each document into results. The results parameter must be a pointer to a slice. recommend to use All() in struct Query or Aggregate

func (*Cursor) Close

func (c *Cursor) Close() error

Close closes this cursor. Next and TryNext must not be called after Close has been called. When the cursor object is no longer in use, it should be actively closed

func (*Cursor) Err

func (c *Cursor) Err() error

Err return the last error of Cursor, if no error occurs, return nil

func (*Cursor) Next

func (c *Cursor) Next(result interface{}) bool

Next gets the next document for this cursor. It returns true if there were no errors and the cursor has not been exhausted.

type CursorI

type CursorI interface {
	Next(result interface{}) bool
	Close() error
	Err() error
	All(results interface{}) error
}

CursorI Cursor interface

type Database

type Database struct {
	// contains filtered or unexported fields
}

Database is a handle to a MongoDB database

func (*Database) Collection

func (d *Database) Collection(name string) *Collection

Collection gets collection from database

func (*Database) DropDatabase

func (d *Database) DropDatabase(ctx context.Context) error

DropDatabase drops database

func (*Database) GetDatabaseName

func (d *Database) GetDatabaseName() string

GetDatabaseName returns the name of database

func (*Database) RunCommand

func (d *Database) RunCommand(ctx context.Context, runCommand interface{}, opts ...opts.RunCommandOptions) *mongo.SingleResult

RunCommand executes the given command against the database.

The runCommand parameter must be a document for the command to be executed. It cannot be nil. This must be an order-preserving type such as bson.D. Map types such as bson.M are not valid. If the command document contains a session ID or any transaction-specific fields, the behavior is undefined.

The opts parameter can be used to specify options for this operation (see the options.RunCmdOptions documentation).

func (*Database) RunCommandCursor

func (d *Database) RunCommandCursor(ctx context.Context, runCommand interface{}, opts ...opts.RunCommandOptions) (*mongo.Cursor, error)

type DeleteResult

type DeleteResult struct {
	DeletedCount int64 // The number of documents deleted.
}

DeleteResult is the result type returned by DeleteOne and DeleteMany operations.

type InsertManyResult

type InsertManyResult struct {
	// The _id values of the inserted documents. Values generated by the driver will be of type primitive.ObjectID.
	InsertedIDs []interface{}
}

InsertManyResult is a result type returned by an InsertMany operation.

type InsertOneResult

type InsertOneResult struct {
	// The _id of the inserted document. A value generated by the driver will be of type primitive.ObjectID.
	InsertedID interface{}
}

InsertOneResult is the result type returned by an InsertOne operation.

type Pipeline

type Pipeline []bson.D

Pipeline define the pipeline for aggregate

type QmgoClient

type QmgoClient struct {
	*Collection
	*Database
	*Client
}

QmgoClient specifies the instance to operate mongoDB

func Open

func Open(ctx context.Context, conf *Config, o ...options.ClientOptions) (cli *QmgoClient, err error)

Open creates client instance according to config QmgoClient can operates all qmgo.client 、qmgo.database and qmgo.collection

type Query

type Query struct {
	// contains filtered or unexported fields
}

Query struct definition

func (*Query) All

func (q *Query) All(result interface{}) error

All query multiple records that meet the filter conditions The static type of result must be a slice pointer

func (*Query) Apply

func (q *Query) Apply(change Change, result interface{}) error

Apply runs the findAndModify command, which allows updating, replacing or removing a document matching a query and atomically returning either the old version (the default) or the new version of the document (when ReturnNew is true)

The Sort and Select query methods affect the result of Apply. In case multiple documents match the query, Sort enables selecting which document to act upon by ordering it first. Select enables retrieving only a selection of fields of the new or old document.

When Change.Replace is true, it means replace at most one document in the collection and the update parameter must be a document and cannot contain any update operators; if no objects are found and Change.Upsert is false, it will returns ErrNoDocuments. When Change.Remove is true, it means delete at most one document in the collection and returns the document as it appeared before deletion; if no objects are found, it will returns ErrNoDocuments. When both Change.Replace and Change.Remove are false,it means update at most one document in the collection and the update parameter must be a document containing update operators; if no objects are found and Change.Upsert is false, it will returns ErrNoDocuments.

reference: https://docs.mongodb.com/manual/reference/command/findAndModify/

func (*Query) Count

func (q *Query) Count() (n int64, err error)

Count count the number of eligible entries

func (*Query) Cursor

func (q *Query) Cursor() CursorI

Cursor gets a Cursor object, which can be used to traverse the query result set After obtaining the CursorI object, you should actively call the Close interface to close the cursor

func (*Query) Distinct

func (q *Query) Distinct(key string, result interface{}) error

Distinct gets the unique value of the specified field in the collection and return it in the form of slice result should be passed a pointer to slice The function will verify whether the static type of the elements in the result slice is consistent with the data type obtained in mongodb reference https://docs.mongodb.com/manual/reference/command/distinct/

func (*Query) Hint

func (q *Query) Hint(hint interface{}) QueryI

Hint sets the value for the Hint field. This should either be the index name as a string or the index specification as a document. The default value is nil, which means that no hint will be sent.

func (*Query) Limit

func (q *Query) Limit(n int64) QueryI

Limit limits the maximum number of documents found to n The default value is 0, and 0 means no limit, and all matching results are returned When the limit value is less than 0, the negative limit is similar to the positive limit, but the cursor is closed after returning a single batch result. Reference https://docs.mongodb.com/manual/reference/method/cursor.limit/index.html

func (*Query) One

func (q *Query) One(result interface{}) error

One query a record that meets the filter conditions If the search fails, an error will be returned

func (*Query) Select

func (q *Query) Select(projection interface{}) QueryI

Select is used to determine which fields are displayed or not displayed in the returned results Format: bson.M{"age": 1} means that only the age field is displayed bson.M{"age": 0} means to display other fields except age When _id is not displayed and is set to 0, it will be returned to display

func (*Query) Skip

func (q *Query) Skip(n int64) QueryI

Skip skip n records

func (*Query) Sort

func (q *Query) Sort(fields ...string) QueryI

Sort is Used to set the sorting rules for the returned results Format: "age" or "+age" means to sort the age field in ascending order, "-age" means in descending order When multiple sort fields are passed in at the same time, they are arranged in the order in which the fields are passed in. For example, {"age", "-name"}, first sort by age in ascending order, then sort by name in descending order

type QueryI

type QueryI interface {
	Sort(fields ...string) QueryI
	Select(selector interface{}) QueryI
	Skip(n int64) QueryI
	Limit(n int64) QueryI
	One(result interface{}) error
	All(result interface{}) error
	Count() (n int64, err error)
	Distinct(key string, result interface{}) error
	Cursor() CursorI
	Apply(change Change, result interface{}) error
	Hint(hint interface{}) QueryI
}

QueryI Query interface

type ReadPref

type ReadPref struct {
	// MaxStaleness is the maximum amount of time to allow a server to be considered eligible for selection.
	// Supported from version 3.4.
	MaxStalenessMS int64 `json:"maxStalenessMS"`
	// indicates the user's preference on reads.
	// PrimaryMode as default
	Mode readpref.Mode `json:"mode"`
}

ReadPref determines which servers are considered suitable for read operations.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is an struct that represents a MongoDB logical session

func (*Session) AbortTransaction

func (s *Session) AbortTransaction(ctx context.Context) error

AbortTransaction aborts the active transaction for this session. This method will return an error if there is no active transaction for this session or the transaction has been committed or aborted.

func (*Session) EndSession

func (s *Session) EndSession(ctx context.Context)

EndSession will abort any existing transactions and close the session.

func (*Session) StartTransaction

func (s *Session) StartTransaction(ctx context.Context, cb func(sessCtx context.Context) (interface{}, error)) (interface{}, error)

StartTransaction starts transaction precondition: - version of mongoDB server >= v4.0 - Topology of mongoDB server is not Single At the same time, please pay attention to the following

  • make sure all operations in callback use the sessCtx as context parameter
  • Dont forget to call EndSession if session is not used anymore
  • if operations in callback takes more than(include equal) 120s, the operations will not take effect,
  • if operation in callback return qmgo.ErrTransactionRetry, the whole transaction will retry, so this transaction must be idempotent
  • if operations in callback return qmgo.ErrTransactionNotSupported,
  • If the ctx parameter already has a Session attached to it, it will be replaced by this session.

type UpdateResult

type UpdateResult struct {
	MatchedCount  int64       // The number of documents matched by the filter.
	ModifiedCount int64       // The number of documents modified by the operation.
	UpsertedCount int64       // The number of documents upsert by the operation.
	UpsertedID    interface{} // The _id field of the upsert document, or nil if no upsert was done.
}

UpdateResult is the result type returned from UpdateOne, UpdateMany, and ReplaceOne operations.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL