qmgo

package module
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2020 License: Apache-2.0 Imports: 12 Imported by: 158

README

Qmgo

Build Status Coverage Status Go Report Card GitHub release GoDoc

简体中文

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

  • Qmgo can allow user 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.

Installation

The recommended way is to use go mod to automatically install dependencies by import github.com/qiniu/qmgo and build .

Of course, the following methods are also feasible:

go get github.com/qiniu/qmgo

Usage

  • Start

import and create a new connection

import (
    "context"
  
    "github.com/qiniu/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, we recommend using the following more convenient way to initialize the connection. All operations are based on cli and no longer need to care about the database and collection.

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

After the initialization is successful, please defer to close the connection

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 oneUserInfo = UserInfo{
    Name: "xm",
    Age: 7,
    Weight: 40,
}

Create index

cli.EnsureIndexes(ctx, []string{}, []string{"age", "name,weight"})
  • Insert a document
// insert one document
result, err := cli.Insert(ctx, oneUserInfo)
  • Find a document
// find one document
  one := UserInfo{}
  err = cli.Find(ctx, bson.M{"name": oneUserInfo.Name}).One(&one)
  • Delete documents
err = cli.Remove(ctx, bson.M{"age": 7})
  • Insert multiple data
// multiple insert
var batchUserInfoI = []interface{}{
	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, batchUserInfoI)
  • 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)

Feature

  • CRUD to documents
  • Create indexes
  • Sort、limit、count、select
  • Cursor
  • Aggregate

qmgo vs mgo 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)

contributing

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

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 = errors.New(mongo.ErrNoDocuments.Error())
)

Functions

func IsDup

func IsDup(err error) bool

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

func IsErrNoDocuments added in v0.5.3

func IsErrNoDocuments(err error) bool

IsErrNoDocuments check if err is no documents, both mongo-go-driver error and qmgo custom error

func NewObjectID added in v0.5.3

func NewObjectID() primitive.ObjectID

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

func Now added in v0.5.1

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 Client

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

Client creates client to mongo

func NewClient

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

NewClient creates mongo.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) Ping

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

Ping confirm connection is alive

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{}) AggregateI

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

func (*Collection) CloneCollection

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

CloneCollection creates a copy of the Collection

func (*Collection) DeleteAll

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

DeleteAll 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) DropCollection

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

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

func (*Collection) EnsureIndexes

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

EnsureIndexes creates unique and non-unique indexes in collection

func (*Collection) Find

func (c *Collection) Find(ctx context.Context, filter interface{}) 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{}) (result *InsertManyResult, err error)

InsertMany executes an insert command to insert multiple documents into the collection. e.g. docs := []interface{}{myDocsInstance1, myDocsInstance2} TODO need a function which translate slice to []interface Reference: https://docs.mongodb.com/manual/reference/command/insert/

func (*Collection) InsertOne

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

InsertOne insert one document into the collection Reference: https://docs.mongodb.com/manual/reference/command/insert/

func (*Collection) Remove

func (c *Collection) Remove(ctx context.Context, filter interface{}) (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) RemoveId added in v0.5.3

func (c *Collection) RemoveId(ctx context.Context, id string) (err error)

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

func (*Collection) UpdateAll

func (c *Collection) UpdateAll(ctx context.Context, filter interface{}, update interface{}) (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) UpdateOne added in v0.5.2

func (c *Collection) UpdateOne(ctx context.Context, filter interface{}, update interface{}) 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{}) (result *UpdateResult, err error)

Upsert updates one documents if filter match, inserts one document if filter is not match 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"`
	// 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"`
}

Config for initial mongodb instance

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(reuslts 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

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) (cli *QmgoClient, err error)

Open creates client instance according to config QmgoClient can operates all mongo.client 、mongo.database and mongo.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) 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) 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
}

QueryI Query interface

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 upserted by the operation.
	UpsertedID    interface{} // The _id field of the upserted document, or nil if no upsert was done.
}

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

Jump to

Keyboard shortcuts

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