easymongo

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2021 License: MIT Imports: 21 Imported by: 1

README

0.x project - not ready for the light of day

Coming soon to an IDE near you... Build Status Coverage Status Go Reference Docs

Easy Mongo

This project aims to be a friendly (somewhat opinionated) abstraction on top of mongo-go-driver. The official driver provides much more fine-grained control than this project attempts to solve.

Get Connected

easymongo supports standard URI connection strings. All you have to do is call Connect() (A note that srv DNS records are not yet supported - this is currently a go limitation)

// Connect to a locally running container
conn := easymongo.Connect("mongo://127.0.0.1")
type myObj struct {}
foo := myObj{}
err = conn.D("my_db").C("my_coll").Insert().One(&foo)

Don't want to go through the arduous process of setting up a local mongo environment? You can spawn a container for the life of a test by using github.com/tophergopher/mongotest:

useDockerContainer := true
// conn is a mongotest.TestConnection object which embeds an easymongo.Connection object
// When this command runs, a mongo docker container is spawned, bound on any available port
// and an easymongo connection is made. This connection object can be used just like a
// standard easymongo.Connection object
conn, err := mongotest.NewTestConnection(useDockerContainer)
// Find the first document with name sorted in descending order
err = conn.Find().Sort("-name").Skip(1).Limit(2).One(bson.M{"name": bson.M{"$ne": nil}})
// Then kill the test container
conn.KillMongoContainer()

C.R.U.D. Examples

Create/Read/Update/Destroy!

Get Data into the Database

Let's talk about first how to get data into the database. Create a struct and add some reflection tags. These tags map to which field gets written. For example:

type Enemy struct {
	ID            primitive.ObjectID `bson:"_id"`
	Name          string             `bson:"name"`
	Notes         string             `bson:"notes,omitempty"`
	LastEncounter *time.Time         `bson:"lastEncounter"`
	Deceased      bool               `bson:"deceased"`
	TimesFought   int                `bson:"timesFought"`
	Evilness      float64            `bson:"evilness"`
}
var theJoker = Enemy{
  ID: primitive.NewObjectID(),
  Name: "The Joker",
  Notes: "Follow-up about his scars.",
  TimesFought: 3,
  Evilness: 92.6,
}

Cool - so now we have an object - let's insert it:

  id, err := coll.Insert().One(theJoker)

Hooray! The document is in the database! Other typical endings for Insert() are .Many(), which will insert a slice of any type (but with a small O(N) overhead), and .ManyFromInterfaceSlice(), which doesn't incur the O(N) overhead but requires you to rewrite slices to a slice of interface.

Find it and query it back

Find the first matching document:

  var eLookup Enemy
  err := coll.Find(bson.M{"name": "The Joker"}).One(&eLookup)
  fmt.Printf("%#v\n", eLookup)

If you examine eLookup, eLookup will be populated with all the initial metadata from theJoker object.

Here's an example which leverages more flags to look-up all entries in the database and loads them into the enemies slice.

  var enemies []Enemy
  err := coll.Find(bson.M{}).Comment(
			"Isn't this a fun query?").BatchSize(5).Projection(
			bson.M{"name": 1}).Hint("name").Sort(
			"-name").Skip(0).Limit(0).Timeout(time.Hour).All(&enemies)
Modify it

Let's say Batman runs into the Joker, Alfred will need to update the last time they ran into eachother:

	err := coll.Update(bson.M{"name": "The Joker"}, bson.M{
			"$set": bson.M{"lastEncounter": time.Now()}}).One()

You'll note that we can end with either .One() or .Many().

Find and mutate

What about if you want to return a document AND mutate it in some groovy way? Find.OneAnd() is your friend!

  var enemyBefore Enemy
  filter := bson.M{"name": "The Joker"}
  set := bson.M{"$set": bson.M{"notes": "What's his endgame?"}}
  err := coll.Find(filter).OneAnd(&enemyBefore).Update(set)

This would return the object prior to being updated. Other endings to OneAnd are Replace() and Delete(). If you want the resultant object after the mutation takes place, then add ReturnDocumentAfterModification() to the chain.

Delete it

When The Joker breaks into The Bat Cave, he wants to delete all of Batman's data. This would delete all documents for enemies encountered in the last 6 months:

  filter := bson.M{"lastEncounter": bson.M{
    "$gte": time.Now().AddDate(0, -6, 0),
    },
  },
  err := coll.Delete(filter).Many()

.One() is also available for individual document deletions using a filter.

Mutate by ID

A note that all of the various CRUD operators have ObjectID helpers FindByID, DeleteByID, UpsertByID, ReplaceByID. If you have the ObjectID in memory, it is one of the fastest methods for updating an object.

  replacementEntry := Enemy{ID: theJoker.ID, Name: "Who knows?"}
  err := coll.ReplaceByID(theJoker.ID, replacementEntry)
Why use easymongo?

You should use easymongo if:

  • You are planning on connecting primarily to a single cluster or instance
  • Are looking to make common query operations with fewer lines of code
  • Are okay with some logic being extrapolated and defaults assumed
  • You can accept one developer's opinionated approach to mongo in golang ;-)

The mongo-go-driver was written with the mindset of allowing complete control of every part of the query process. This project aims to build on that power, aiming to make integrating your project with mongo easier.

This can be run alongside mongo-go-driver in the same project without fear of conflicts. In fact, you can call easymongo.ConnectUsingMongoClient(client *mongo.Client) if you already have a pre-initialized mongo.Client and are considering trying easymongo. You will be able to start consuming the easymongo.Connection methods immediately.

How are things different from mongo-go-driver?

Some functionality (such as the ability to directly set the context on a query) has been abstracted, while other functionality has intentionally been ignored in order to keep it simple for the core use cases. If you still want to set a context, you can explicitly set it with SetContext(ctx) on any Query object.

This project is built on top of mongo-go-driver, so if you desire additional power (and really, who doesn't?), you can call MongoDriverClient() on the Connection object to obtain direct access to the *mongo.Client object. From there, the world is your oyster.

The decision (which I expect to see at least 1 GitHub issue debating) was made to cache the most recent mongo connection in a global variable under the covers in easymongo. This means that once a connection is initialized, conn := easymongo.GetCurrentConnection() will return the most recent initialized DB connection object. This allows for easy conversion to mongo without the need to change dozens of function headers to expose the connection.

Contributors

Anyone is welcome to submit PRs. Please ensure there is test coverage before submitting the request.

Documentation

Index

Constants

View Source
const (
	// DefaultPrimary attempts to read and write to the primary node. Secondary will be read from if primary isn't available.
	DefaultPrimary = ReadConcernLocal | ReadPreferencePrimaryPreferred | WriteConcernW1
	// DefaultSecondary reads by default from a secondary node (if available). It will use majority consensus when reading to determine what data to return.
	DefaultSecondary = ReadConcernMajority | ReadPreferenceSecondaryPreferred | WriteConcernW1
	// DefaultAnywhere connects to the first available node (primary or secondary) for reading. It uses majority both for write confirmations and while waiting for reads.
	DefaultAnywhere = ReadConcernMajority | ReadPreferenceNearest | WriteConcernMajority
)

Variables

View Source
var (
	// ErrNotImplemented is raised when a function is not yet supported/complete
	// This is mostly used to help track development progress
	ErrNotImplemented = NewMongoErr(errors.New("this feature has not yet been implemented"))
	// ErrTimeoutOccurred denotes a query exceeded the max call time it was allowed
	ErrTimeoutOccurred = NewMongoErr(errors.New("timeout during database transaction"))
	// ErrPointerRequired denotes that the provided result object is being passed by value rather than reference
	ErrPointerRequired = NewMongoErr(errors.New("a pointer is required in order to unpack the resultant value from a query"))
	// ErrNoDocuments denotes no documents were found
	ErrNoDocuments = NewMongoErr(mongo.ErrNoDocuments)
	// ErrWrongType indicates the specified distinct operation did not work. Check the field type that you are attempting to use distinct on.
	ErrWrongType = NewMongoErr(errors.New("the type specified could not be decoded into"))
)

Functions

func GetTimeoutCtx added in v0.0.9

func GetTimeoutCtx(timeout *time.Duration) (ctx context.Context, cancel context.CancelFunc)

GetTimeoutCtx returns a context based on if a timeout has been specified. If no timeout was specified, then context.Background() is returned.

Types

type AggregationQuery added in v0.0.20

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

func (*AggregationQuery) All added in v0.0.20

func (p *AggregationQuery) All(result interface{}) error

All executes the aggregation and returns the resultant output to the provided result object.

func (*AggregationQuery) AllowDiskUse added in v0.0.20

func (p *AggregationQuery) AllowDiskUse() *AggregationQuery

AllowDiskUse sets a flag which allows queries to page to disk space should they exhaust their allotted memory.

func (*AggregationQuery) BatchSize added in v0.0.20

func (p *AggregationQuery) BatchSize(n int) *AggregationQuery

BatchSize overrides the batch size for how documents are returned.

func (*AggregationQuery) BypassDocumentValidation added in v0.0.20

func (p *AggregationQuery) BypassDocumentValidation() *AggregationQuery

TODO: BypassDocumentValidation options docs

func (*AggregationQuery) Collation added in v0.0.20

Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks. https://docs.mongodb.com/manual/reference/collation/ TODO: Create helpers and consts for Collation

func (*AggregationQuery) Comment added in v0.0.20

func (p *AggregationQuery) Comment(comment string) *AggregationQuery

Comment adds a comment to the query - when the query is executed, this comment can help with debugging from the logs.

func (*AggregationQuery) Cursor added in v0.0.20

func (p *AggregationQuery) Cursor() (*mongo.Cursor, error)

Cursor executes the query using the provided options and returns the mongo.Cursor that can be worked with directly. This is typically useful when returning large numbers of results. If you just need to get at the documents without iterating, call .One() or .All()

func (*AggregationQuery) Hint added in v0.0.20

func (p *AggregationQuery) Hint(indexKeys ...string) *AggregationQuery

Hint allows a user to specify index key(s) and supplies these to .hint() - this can result in query optimization. This should either be the index name as a string or the index specification as a document. The following example would instruct mongo to use a field called 'age' as a look-up index. Mongo CLI: db.users.find().hint( { age: 1 } ) easymongo: err = conn.Collection(

"users").Find(bson.M{}).Hint("age").One(&userObj)

Reference: https://docs.mongodb.com/manual/reference/operator/meta/hint/ TODO: Support '-' prepending - shoul it be -1 or 0 as the value?

func (*AggregationQuery) One added in v0.0.20

func (p *AggregationQuery) One(result interface{}) error

One executes the aggregation and returns the first result to the provided result object.

func (*AggregationQuery) Timeout added in v0.0.20

Timeout uses the provided duration to set a timeout value using a context. The timeout clock begins upon query execution (e.g. calling .All()), not at time of calling Timeout().

func (*AggregationQuery) WithContext added in v0.0.20

func (p *AggregationQuery) WithContext(ctx context.Context) *AggregationQuery

WithContext will consume the supplied context. A note that this is completely optional as Timeout will auto-create a context for you if one is not supplied. This is typically useful when using a context across many functions.

type Collection

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

Collection is a helper for accessing and modifying mongo collections

func GetCollection

func GetCollection(dbName, collectionName string) *Collection

GetCollection is a shorthand for getting a collection by name using the globally initialized database. Consider using db.Collection() if you wish to explicitly consume a given connection pool.

func (*Collection) Aggregate added in v0.0.20

func (c *Collection) Aggregate(pipeline interface{}) *AggregationQuery

Aggregate begins an aggregationQuery pipeline. The pipeline will be executed on a call to coll.Aggregate().All() or coll.Agregate().One()

func (*Collection) Connection

func (c *Collection) Connection() *Connection

Connection returns the connection associated with this collection.

func (*Collection) Count

func (c *Collection) Count() (int, error)

Count returns the number of documents in the collection. When working with larger document sets, collection.EstimatedCount can also be a friend. If you wish to add filters to query a count, then use collection.Find(filterQuery).Count()

func (*Collection) Delete added in v0.0.9

func (c *Collection) Delete(filter interface{}) *DeleteQuery

Delete helps construct and execute deletion queries. Use with .One and .Many

func (*Collection) DeleteByID

func (c *Collection) DeleteByID(id primitive.ObjectID) (err error)

DeleteByID assumes that an ID is an ObjectID and the ID is located at _id.

func (*Collection) Drop added in v0.0.6

func (c *Collection) Drop() (err error)

Drop drops the collection this object is referring to.

func (*Collection) EstimatedCount added in v0.0.20

func (c *Collection) EstimatedCount() (int, error)

EstimatedCount returns the estimated count of the documents in the collection For a precise count, try collection.Count()

func (*Collection) Find

func (c *Collection) Find(filter interface{}) (q *FindQuery)

Find allows a user to execute a standard find() query. findOne(), find() and findAnd*() are executed when a user calls:

q.One(), q.Many(). q.FindAnd().Replace(), q.FindAnd().Update(), q.FindAnd().Delete()

TODO: Consider using bsoncore.Doc rather than interface?

func (*Collection) FindByDate

func (c *Collection) FindByDate(after *time.Time, before *time.Time, additionalFilters bson.M) *FindQuery

FindByDate is a helper for filtering documents by times using the ObjectID. This is typically helpful when dealing with large collections as Skip and Limit will become less performant.

func (*Collection) FindByID

func (c *Collection) FindByID(id interface{}, result interface{}) (err error)

FindByID wraps Find, ultimately executing `findOne("_id": providedID)` Typically, the provided id is a pointer to a *primitive.ObjectID.

func (*Collection) GetDatabase

func (c *Collection) GetDatabase() *Database

GetDatabase returns the database associated with the database/collection.

func (*Collection) Index added in v0.0.9

func (c *Collection) Index(indexNames ...string) *Index

Index returns an object that can be actioned upon. Compound indices can be specified by passing in multiple strings

func (*Collection) Insert

func (c *Collection) Insert() *InsertQuery

Insert constructs and returns an InsertQuery object. Now run .One() or .Many() using this handle.

func (*Collection) MongoDriverCollection added in v0.0.6

func (c *Collection) MongoDriverCollection() *mongo.Collection

MongoDriverCollection returns the native mongo driver collection object (should you wish to interact with it directly)

func (*Collection) Name added in v0.0.24

func (c *Collection) Name() string

Name returns the name of the Collection in scope

func (*Collection) Replace

func (c *Collection) Replace(filter interface{}, obj interface{}) *ReplaceQuery

Replace returns a ReplaceQuery. Trying running `.One()` against this. This is used to replace an entire object. If you are looking to update just part of a document (e.g. $set a field, $inc a counter up or down, etc.) you should instead use collection.Update().One().

func (*Collection) ReplaceByID

func (c *Collection) ReplaceByID(id interface{}, obj interface{}) (err error)

ReplaceByID is a friendly helper that wraps Replace(bson.M{"_id": id}, obj).One()

func (*Collection) Stats added in v0.0.28

func (c *Collection) Stats(adminName, promptName, collectionName string) (*CollectionStats, error)

Stats returns various stats representing metadata in a collection.

func (*Collection) Update added in v0.0.6

func (c *Collection) Update(filter interface{}, update interface{}) *UpdateQuery

Update returns an UpdateQuery object which can be actioned upon by calling One() or Many() e.g. c.Update().Many()

func (*Collection) UpdateByID

func (c *Collection) UpdateByID(id interface{}, update interface{}) (err error)

UpdateByID wraps collection.Update().One() to update a single record by ID (should the record exist).

func (*Collection) Upsert added in v0.0.6

func (c *Collection) Upsert(filter interface{}, updateQuery interface{}) *UpdateQuery

Upsert updates the first matching document using the upsert option once .One() has been called. If no option overrides are necessary, consider using UpsertOne or UpsertByID.

func (*Collection) UpsertAll added in v0.0.20

func (c *Collection) UpsertAll(filter interface{}, updateQuery interface{}) (matchedCount, updatedCount int, err error)

UpsertAll performs an update style upsert using updateMany(). Should no documents match the query, then a new document is created. updateQuery is typically of some sort of bson.M{"$set": bson.M{"someKey": newVal} or $push style operation.

func (*Collection) UpsertByID

func (c *Collection) UpsertByID(id interface{}, updateQuery interface{}) (err error)

UpsertByID performs an upsert style update using the updateQuery against the provided _id.

func (*Collection) UpsertOne

func (c *Collection) UpsertOne(filter interface{}, updateQuery interface{}) error

UpsertOne updates the first matching document using the default upsert options. This call is equivalent to c.Upsert(filter, updateQuery).One()

type CollectionStats added in v0.0.28

type CollectionStats struct {
	// CollectionName is the name of the collection
	CollectionName string `bson:"-"`
	// Namespace is a string of db_name.collection_name
	Namespace string `bson:"ns"`
	// TotalCollectionSizeInMB is the total uncompressed size in memory of all records in a collection.
	// The size does not include the size of any indexes associated with the collection, which the totalIndexSize field reports.
	TotalCollectionSizeInMB int `bson:"size"`
	// CompressedCollectionSizeInMB is the total amount of storage allocated to this collection for document storage. The scale argument affects this value.
	CompressedCollectionSizeInMB int `bson:"storageSize"`
	DataCollectionSizeInMB       int `bson:"totalSize"`
	// NumberOfDocuments is the number of objects or documents in this collection.
	NumberOfDocuments int `bson:"count"`
	// AverageObjectSizeBytes is the average size of an object in the collection.
	AverageObjectSizeBytes int `bson:"avgObjSize"`
	// TotalIndexSizeMB is the total size of all indexes.
	TotalIndexSizeMB int `bson:"totalIndexSize"`
	// NumberOfIndexes is the number of indexes on the collection.
	// All collections have at least one index on the _id field.
	NumberOfIndexes int `bson:"nindexes"`
}

CollectionStats represents various metadata about a collection https://docs.mongodb.com/manual/reference/command/collStats/

type Connection

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

Connection represents a connection to the mongo cluster/instance.

func Connect

func Connect(mongoURI string) *Connection

Connect connects to the given mongo URI. Connect wraps ConnectWith(mongoUri).Connect(). If you are using just a mongoUri for connection, this function should be all you need. However, if you need to configure additional options, it is recommened to instead use ConnectWith().Connect(). If a connection does not suceed when using Connect, then a panic occurs.

func GetCurrentConnection

func GetCurrentConnection() *Connection

GetCurrentConnection returns the current connection cached in the global context.

func (*Connection) D added in v0.0.24

func (conn *Connection) D(dbName string) *Database

D is a shorthand for returning the Database object for the provided database name. It wraps Database() and provides identical functionality.

func (*Connection) Database added in v0.0.6

func (conn *Connection) Database(dbName string) *Database

Database returns the database object associated with the provided database name

func (*Connection) DatabaseByConnectionType added in v0.0.9

func (conn *Connection) DatabaseByConnectionType(dbName string, connectFlag ConnectionFlag) *Database

DatabaseByConnectionType returns the database object associated with the provided database name

func (*Connection) DatabaseNames

func (conn *Connection) DatabaseNames() []string

DatabaseNames returns a list of the databases available in the connected cluster as a list of strings. If an error occurrent, an empty list is returned.

func (*Connection) EnableDebug added in v0.0.24

func (conn *Connection) EnableDebug() error

EnableDebug enables debug, regenerates the client options and reconnects to the mongo client. This should never be done in a production environment unless you're, you know, debugging. The connection is cached as the new global connection If a logger has not been set (using conn.SetLogger)

func (*Connection) ListDatabases

func (conn *Connection) ListDatabases() (dbList []*Database)

ListDatabases returns a list of databases available in the connected cluster as objects that can be interacted with.

func (*Connection) MongoDriverClient

func (conn *Connection) MongoDriverClient() *mongo.Client

MongoDriverClient returns the mongo.Client from mongo-go-driver - to allow for direct interaction with the mongo driver for those users searching for more fine-grained control.

func (*Connection) MongoURI

func (conn *Connection) MongoURI() string

MongoURI returns the URI that the mongo instance is connected to

func (*Connection) Ping

func (conn *Connection) Ping() (err error)

Ping attempts to ping the mongo instance It uses the default ReadPreference specified by the connect's ClientOptions.

func (*Connection) SetLogger added in v0.0.24

func (conn *Connection) SetLogger(logger Logger)

SetLogger overrides a connection's logger object This is used primarily when enabling debug mode

type ConnectionBuilder added in v0.0.9

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

ConnectionBuilder is for specifying options when connecting to a DB

func ConnectWith added in v0.0.9

func ConnectWith(mongoURI string) *ConnectionBuilder

ConnectWith allows one to start building a Connection with Options. Call .Connect() at the end to establish the connection. e.g. err = easymongo.ConnectWith(mongoURI).DefaultTimeout().Connect()

func (*ConnectionBuilder) Connect added in v0.0.9

func (cb *ConnectionBuilder) Connect() (*Connection, error)

Connect performs the actual connection to the DB. A note that calling this function has the side-effect of setting the global cached connection to this value. If you are not using the global connection value and instead using the value explicitly returned from this function, then disregard this side-effect. If a connection does not succeed, then an error is returned.

func (*ConnectionBuilder) ConnectTimeout added in v0.0.9

func (cb *ConnectionBuilder) ConnectTimeout(timeout time.Duration) *ConnectionBuilder

ConnectTimeout allows one to specify the initial timeout when connecting to a database

func (*ConnectionBuilder) Debug added in v0.0.24

func (cb *ConnectionBuilder) Debug() *ConnectionBuilder

Debug will log the raw commands the server is running to the debug level

func (*ConnectionBuilder) DefaultOperationTimeout added in v0.0.9

func (cb *ConnectionBuilder) DefaultOperationTimeout(timeout time.Duration) *ConnectionBuilder

DefaultOperationTimeout allows you to specify a timeout used both for the top-level connection and for any subsequent queries/operations to the database (unless overridden).

func (*ConnectionBuilder) DefaultQueryTimeout added in v0.0.9

func (cb *ConnectionBuilder) DefaultQueryTimeout(timeout time.Duration) *ConnectionBuilder

DefaultQueryTimeout allows you to specify a timeout used for query operations.

func (*ConnectionBuilder) Flags added in v0.0.9

Flags can be used to set one or more connection flags. Consider using Default* options, or use bitwise '|' to specify multiple options e.g.: ConnectWith(mongoURI).Flags(ReadConcernMajority | ReadPreferenceNearest | WriteConcernMajority)

func (*ConnectionBuilder) FromMongoDriverClient added in v0.0.9

func (cb *ConnectionBuilder) FromMongoDriverClient(client *mongo.Client) *Connection

FromMongoDriverClient accepts an initialized mongo.Client. This is useful if you want the power of standing up your own mongo.Client connection externally.

func (*ConnectionBuilder) Logger added in v0.0.24

func (cb *ConnectionBuilder) Logger(logger Logger) *ConnectionBuilder

Logger overrides the default logger in use TODO: Handle nil/deactivating logger

func (*ConnectionBuilder) WithAuth added in v0.0.24

func (c *ConnectionBuilder) WithAuth(creds *options.Credential)

WithAuth injects credentials into mongoOptions

type ConnectionFlag added in v0.0.9

type ConnectionFlag int32
const (
	ReadConcernAvailable ConnectionFlag
	ReadConcernLinearizable
	ReadConcernLocal
	ReadConcernMajority
	ReadConcernSnapshot

	ReadPreferenceNearest
	// ReadPreferencePrimary limits the read to the primary node. If the primary isn't available, the query will error.
	ReadPreferencePrimary
	// ReadPreferencePrimaryPreferred prefers reads from primary, but will fall back
	ReadPreferencePrimaryPreferred
	ReadPreferenceWriteConcern
	ReadPreferenceSecondary
	ReadPreferenceSecondaryPreferred

	WriteConcernJournal
	// WriteConcernW1 waits for a single node in a cluster to acknowledge a write before returning
	WriteConcernW1
	// WriteConcernW2 waits for two nodes in a cluster to acknowledge a write before returning
	WriteConcernW2
	// WriteConcernW3 waits for a three nodes in a cluster to acknowledge a write before returning
	WriteConcernW3
	// WriteConcernMajority waits for a majority of nodes in a cluster to acknowledge a write operation
	// before the query is declared complete.
	WriteConcernMajority
)

type Database

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

Database is helper for representing a database in a cluster.

func GetDatabase

func GetDatabase(dbName string) *Database

GetDatabase returns a database object for the named database using the most recently connected to mongo instance/cluster.

func (*Database) C

func (db *Database) C(name string) *Collection

C returns a Collection object that can be used to run queries on and create/drop indices C wraps Collection() for users who want to use short-hand to do queries. It is interchangeable with a call to db.Collection().

func (*Database) Collection

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

Collection returns a Collection object that can be used to run queries on and create/drop indices It is interchangeable with C().

func (*Database) CollectionNames

func (db *Database) CollectionNames() []string

CollectionNames returns the names of the collections as strings. If no collections could be found, then an empty list is returned.

func (*Database) Drop

func (db *Database) Drop() error

Drop drops a database from a mongo instance. Use with caution.

func (*Database) ListCollections

func (db *Database) ListCollections() ([]*Collection, error)

ListCollections returns a list of Collection objects that can be queried against. If you just need the collection names as strings, use db.CollectionNames() instead

func (*Database) Name

func (db *Database) Name() string

Name returns the name of the database

func (*Database) Run added in v0.0.24

func (db *Database) Run(cmd interface{}, result interface{}) error

TODO: DB.With func (db *Database) With(s *Session) *Database {return } TODO: DB.GridFS func (db *Database) GridFS(prefix string) *GridFS {return } TODO: DB.Run

type DefaultLogger added in v0.0.24

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

func NewDefaultLogger added in v0.0.24

func NewDefaultLogger() *DefaultLogger

NewDefaultLogger returns a DefaultLogger, which implements the Logger interface Under the covers, DefaultLogger calls out to logrus using TextFormatter set to the debug level. If you don't want this behavior, simply implement an interface similar to this one that supports Debugf() and Errorf() calls.

func (*DefaultLogger) Debugf added in v0.0.24

func (logger *DefaultLogger) Debugf(format string, args ...interface{})

func (*DefaultLogger) Errorf added in v0.0.24

func (logger *DefaultLogger) Errorf(format string, args ...interface{})

type DeleteQuery added in v0.0.9

type DeleteQuery struct {
	*Query
}

DeleteQuery stores the data necessary to execute a deletion. collection.Delete() returns an initialized DeleteQuery.

func (*DeleteQuery) Collation added in v0.0.9

func (dq *DeleteQuery) Collation(c *options.Collation) *DeleteQuery

func (*DeleteQuery) Hint added in v0.0.9

func (dq *DeleteQuery) Hint(indexKeys ...string) *DeleteQuery

func (*DeleteQuery) Many added in v0.0.9

func (dq *DeleteQuery) Many() (numDeleted int, err error)

Many calls out to DeleteMany() which deletes all entries matching the filter query provided to Delete().

func (*DeleteQuery) One added in v0.0.9

func (dq *DeleteQuery) One() (err error)

One calls out to DeleteOne() which deletes the first entry matching the filter query provided to Delete().

type ExplainResult

type ExplainResult struct {
	QueryPlanner QueryPlanner `json:"queryPlanner"`
}

ExplainResult represents the results from a query documented here - https://docs.mongodb.com/manual/reference/command/explain/#dbcmd.explain TODO: Test that this actually unpacks and support the other two types of explain results.

type FindAndQuery

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

FindAndQuery is used for Find().OneAnd() operations (e.g. Find().OneAnd().Replace())

func (*FindAndQuery) ArrayFilters added in v0.0.8

func (q *FindAndQuery) ArrayFilters(o *options.ArrayFilters) *FindAndQuery

ArrayFilters is used to hold filters for the array filters CRUD option. If a registry is nil, bson.DefaultRegistry will be used when converting the filter interfaces to BSON. TODO: ArrayFilters helpers

func (*FindAndQuery) BypassDocumentValidation added in v0.0.8

func (q *FindAndQuery) BypassDocumentValidation() *FindAndQuery

TODO: BypassDocumentValidation options docs

func (*FindAndQuery) Delete

func (q *FindAndQuery) Delete() (err error)

Delete ultimately ends up running `findOneAndDelete()`. If you do not need the existing value/object prior to the deletion, it is recommended to instead run `Collection().Delete().One()` mongo.ErrNoDocuments is returned in the case that nothing matches the specified query.

func (*FindAndQuery) Limit added in v0.0.9

func (q *FindAndQuery) Limit(limit int) *FindAndQuery

Limit sets the max value of responses to return when executing the query. A note that when working with larger datasets, it is much more performance to compare using collection.FindByDate

func (*FindAndQuery) Projection added in v0.0.8

func (q *FindAndQuery) Projection(projectionQuery interface{}) *FindAndQuery

Projection limits the information returned from the query. Whitelist fields using: `bson.M{"showThisField": 1}` Blacklist fields using: `bson.M{"someBigStructToHide": 0}`

func (*FindAndQuery) Replace

func (q *FindAndQuery) Replace(replacementObject interface{}) (err error)

Replace ultimately ends up running `findOneAndReplace()`. If you do not need the existing value/object, it is recommended to instead run `collection.Replace().Execute()` mongo.ErrNoDocuments is returned in the case that nothing matches the specified query.

func (*FindAndQuery) ReturnDocumentAfterModification added in v0.0.20

func (q *FindAndQuery) ReturnDocumentAfterModification() *FindAndQuery

ReturnDocumentAfterModification specifies the object should be returned after modification is complete. By default, the document is returned before the query.

func (*FindAndQuery) Skip added in v0.0.9

func (q *FindAndQuery) Skip(skip int) *FindAndQuery

Skip sets the skip value to bypass the given number of entries A note that when working with larger datasets, it is much more performance to compare using collection.FindByDate

func (*FindAndQuery) Timeout added in v0.0.9

func (q *FindAndQuery) Timeout(d time.Duration) *FindAndQuery

Timeout uses the provided duration to set a timeout value using a context. The timeout clock begins upon query execution (e.g. calling .All()), not at time of calling Timeout().

func (*FindAndQuery) Update

func (q *FindAndQuery) Update(updateQuery interface{}) (err error)

Update ends up running `findAndModify()` to update (and return) the first matching document If you do not need the result object, consider running `collection.UpdateOne()` instead. mongo.ErrNoDocuments is returned in the case that nothing matches the specified query.

func (*FindAndQuery) Upsert added in v0.0.8

func (q *FindAndQuery) Upsert() *FindAndQuery

Upsert sets an option to specify that if a document doesn't exist which matches the update filter, then a new document will be created as a result of this query run.

type FindQuery

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

FindQuery is a helper for finding and counting documents

func (*FindQuery) All added in v0.0.20

func (q *FindQuery) All(results interface{}) error

All executes the specified query using find() and unmarshals the result into the provided interface. Ensure interface{} is either a slice or a pointer to a slice.

func (*FindQuery) AllowDiskUse

func (q *FindQuery) AllowDiskUse() *FindQuery

AllowDiskUse sets a flag which allows queries to page to disk space should they exhaust their allotted memory.

func (*FindQuery) AllowPartialResults

func (q *FindQuery) AllowPartialResults() *FindQuery

AllowPartialResults allows an operation on a sharded cluster to return partial results (in the case that a shard is inaccessible). An error will not be returned should only partial results be returned.

func (*FindQuery) BatchSize

func (q *FindQuery) BatchSize(batchSize int) *FindQuery

BatchSize sets the max batch size returned by the server each time the cursor executes. Mostly useful when using Iter directly.

func (*FindQuery) Collation added in v0.0.9

func (q *FindQuery) Collation(c *options.Collation) *FindQuery

Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks. https://docs.mongodb.com/manual/reference/collation/ TODO: Create helpers and consts for Collation

func (*FindQuery) Comment added in v0.0.9

func (q *FindQuery) Comment(comment string) *FindQuery

Comment adds a comment to the query - when the query is executed, this comment can help with debugging from the logs.

func (*FindQuery) Count

func (q *FindQuery) Count() (int, error)

Count counts the number of documents using the specified query

func (*FindQuery) Cursor added in v0.0.20

func (q *FindQuery) Cursor() (*mongo.Cursor, error)

Cursor results the mongo.Cursor. This is useful when working with large numbers of results. Alternatively, consider calling collection.Find().One() or collection.Find().All().

func (*FindQuery) Distinct added in v0.0.22

func (q *FindQuery) Distinct(fieldName string) (interfaceSlice []interface{}, err error)

Distinct returns an array of the distinct elements in the provided fieldName. A note that interfaceSlice does not contain the full document but rather just the value from the provided field. Sort/Limit/Skip are presently ignored.

func (*FindQuery) DistinctFloat64s added in v0.0.24

func (q *FindQuery) DistinctFloat64s(fieldName string) (floatSlice []float64, err error)

DistinctFloat64s returns a list of distinct float64s for a given field.

func (*FindQuery) DistinctInts added in v0.0.24

func (q *FindQuery) DistinctInts(fieldName string) (intSlice []int, err error)

DistinctInts returns a list of distinct integers for a given field.

func (*FindQuery) DistinctStrings added in v0.0.22

func (q *FindQuery) DistinctStrings(fieldName string) (stringSlice []string, err error)

DistinctStrings returns a distinct list of strings using the provided query/field name. Sorting/Limiting/Skipping are supported, with the caveat that only the Skip/Sort/Limit options are supported

coll.Find().Sort(fieldName).Limit(2).Skip(1).DistinctStrings(fieldName)

func (*FindQuery) Hint added in v0.0.9

func (q *FindQuery) Hint(indexKeys ...string) *FindQuery

Hint allows a user to specify index key(s) and supplies these to .hint() - this can result in query optimization. This should either be the index name as a string or the index specification as a document. The following example would instruct mongo to use a field called 'age' as a look-up index. Mongo CLI: db.users.find().hint( { age: 1 } ) easymongo: err = conn.Collection(

"users").Find(bson.M{}).Hint("age").One(&userObj)

Reference: https://docs.mongodb.com/manual/reference/operator/meta/hint/ TODO: Support '-' prepending - shoul it be -1 or 0 as the value?

func (*FindQuery) Limit

func (q *FindQuery) Limit(limit int) *FindQuery

Limit sets the max value of responses to return when executing the query. A note that when working with larger datasets, it is much more performance to compare using collection.FindByDate

func (*FindQuery) One

func (q *FindQuery) One(result interface{}) (err error)

One consumes the specified query and marshals the result into the provided interface.

func (*FindQuery) OneAnd

func (q *FindQuery) OneAnd(result interface{}) *FindAndQuery

OneAnd consumes the specified query and marshals the result into the provided interface once .Replace() or .Update() are called.

func (*FindQuery) Projection

func (q *FindQuery) Projection(projectionQuery interface{}) *FindQuery

Projection limits the information returned from the query. Whitelist fields using: `bson.M{"showThisField": 1}` Blacklist fields using: `bson.M{"someBigStructToHide": 0}`

func (*FindQuery) Skip

func (q *FindQuery) Skip(skip int) *FindQuery

Skip sets the skip value to bypass the given number of entries A note that when working with larger datasets, it is much more performance to compare using collection.FindByDate

func (*FindQuery) Sort added in v0.0.9

func (q *FindQuery) Sort(fields ...string) *FindQuery

Sort accepts a list of strings to use as sort fields. Prepending a field name with a '-' denotes descending sorting e.g. "-name" would sort the "name" field in descending order

func (*FindQuery) Timeout added in v0.0.9

func (q *FindQuery) Timeout(d time.Duration) *FindQuery

Timeout uses the provided duration to set a timeout value using a context. The timeout clock begins upon query execution (e.g. calling .All()), not at time of calling Timeout().

type Index

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

Index represents a helper for manipulating database indices

func (*Index) Collection added in v0.0.9

func (i *Index) Collection() *Collection

Collection returns the collection object associated with this index

func (*Index) Drop added in v0.0.9

func (i *Index) Drop() (err error)

TODO: Index.Drop() drops an index from the database

func (*Index) Ensure added in v0.0.9

func (i *Index) Ensure() (indexName string, err error)

Ensure ensures that an index exists.

func (*Index) Load added in v0.0.9

func (i *Index) Load() (err error)

TODO: Index.Load() loads an index from the database into memory

type InputStage

type InputStage struct {
	Stage       string        `json:"stage"`
	InputStages []interface{} `json:"inputStages"`
}

type InsertQuery

type InsertQuery struct {
	*Query
}

InsertQuery is a helper for constructing insertion operations

func (*InsertQuery) Many

func (iq *InsertQuery) Many(objsToInsert interface{}) (ids []*primitive.ObjectID, err error)

Many inserts a slice into a mongo collection. The ids of the inserted objects are returned. If an ID was not available (e.g. it was unset), an empty entry in the slice is returned. TODO: What should be the default behavior when an ID isn't returned? Note: Many() uses reflect to coerce an interface to an interface slice. This results in a minor O(N) performance hit. If inserting large quanities of items and every nanosecond counts, cast your slice to a slice interface yourself (which is an O(1) operation), and call ManyFromInterfaceSlice().

func (*InsertQuery) ManyFromInterfaceSlice

func (iq *InsertQuery) ManyFromInterfaceSlice(objsToInsert []interface{}) (ids []*primitive.ObjectID, err error)

ManyFromInterfaceSlice inserts an interface slice into a mongo collection If you need to insert large quantities of items and every nanosecond matters, then use this function instead of Many.

func (*InsertQuery) One

func (iq *InsertQuery) One(objToInsert interface{}) (id *primitive.ObjectID, err error)

One is used to insert a single object into a collection

type Logger added in v0.0.24

type Logger interface {
	// WithField(msg string, arg interface{}) Logger
	// WithFields(fields map[string]interface{}) Logger
	Debugf(format string, args ...interface{})
	// Debugf(format string, args ...interface{})
	// Info(args ...interface{})
	// Infof(format string, args ...interface{})
	// Warn(args ...interface{})
	// Warnf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
}

Logger represents a common interface that is consumed by easymongo. Add wrappers around

e.g. ConnectWith().Logger(Logger).Connect()

type MongoConnectOptions

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

MongoConnectOptions holds helpers for configuring a new mongo connection.

type MongoErr

type MongoErr struct {
	Message string `json:"message"`
	// contains filtered or unexported fields
}

MongoErr represents any kind of mongo error, regardless of which component of mongo-go-driver threw the error.

func NewMongoErr

func NewMongoErr(err error) (me MongoErr)

NewMongoErr casts any error to a MongoErr. This is intended to help extrapolate all mongo errors into a single class. Should be used as:

if v := errors.Is(err, mongo.Error) {
		merr := NewMongoErr(err)
}

TODO: Should we be using this?

func (MongoErr) Error

func (me MongoErr) Error() string

func (MongoErr) Unwrap

func (me MongoErr) Unwrap() error

type ParsedQuery

type ParsedQuery struct {
}

type Plan

type Plan struct {
	Stage      string     `json:"stage"`
	InputStage InputStage `json:"inputStage"`
}

type Query

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

Query is used for creating To create a query, call a relevant function off of a Collection. The following line would return a *Query object:

`q := GetDatabase("db_name").C("collection_name").Find(bson.M{"alignment": "Chaotic Neutral"})`

And that can be consumed as such:

`var weirdCharacters []Character`
`err = q.Skip(5).Limit(10).Timeout(time.Minute).All(&weirdCharacters)``

The previous lines would: - Access db_name.collection_name - Setup the query filter(s) to skip the first 5 entries and limit to 10 entries max - timing out the query after 1 minute. - Run the find() query looking for records matching {"alignment": "Chaotic Neutral"} - Unpack the results into the weirdCharacters slice

type QueryPlanner

type QueryPlanner struct {
	PlannerVersion    string      `json:"plannerVersion"`
	Namespace         string      `json:"namespace"`
	IndexFilterSet    bool        `json:"indexFilterSet"`
	ParsedQuery       ParsedQuery `json:"parsedQuery"`
	QueryHash         string      `json:"queryHash"`
	PlanCacheKey      string      `json:"planCacheKey"`
	OptimizedPipeline bool        `json:"optimizedPipeline"`
	WinningPlan       Plan        `json:"winningPlan"`
	RejectedPlans     []Plan      `json:"rejectedPlans"`
}

type ReplaceQuery

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

ReplaceQuery is a helper for replacement query actions and options.

func (*ReplaceQuery) One added in v0.0.9

func (rq *ReplaceQuery) One() error

Execute runs the ReplaceQuery. No actions are taken until this query is run.

type UpdateQuery

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

UpdateQuery helps construct and execute update queries

func (*UpdateQuery) All added in v0.0.20

func (uq *UpdateQuery) All() (matchedCount, updatedCount int, err error)

All runs the UpdateQuery against all matching documents. A note that the updatedCount includes the count for upserted documents. No actions are taken until this function is called.

func (*UpdateQuery) ArrayFilters added in v0.0.6

func (uq *UpdateQuery) ArrayFilters(o *options.ArrayFilters) *UpdateQuery

ArrayFilters is used to hold filters for the array filters CRUD option. If a registry is nil, bson.DefaultRegistry will be used when converting the filter interfaces to BSON. TODO: ArrayFilters helpers

func (*UpdateQuery) BypassDocumentValidation added in v0.0.6

func (uq *UpdateQuery) BypassDocumentValidation() *UpdateQuery

TODO: BypassDocumentValidation options docs

func (*UpdateQuery) One added in v0.0.6

func (uq *UpdateQuery) One() (err error)

One runs the UpdateQuery against the first matching document. No actions are taken until this function is called.

func (*UpdateQuery) Upsert added in v0.0.6

func (uq *UpdateQuery) Upsert() *UpdateQuery

Upsert specifies that if a document doesn't exist that matches the update filter, then a new document will be created as a result of this query run.

type UpdateQueryConstructor

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

UpdateQueryConstructor is a helper for easily crafting update queries. TODO: Support multiple calls to each block with unique field names, right now, calling .Increment().Increment() would only increment the last field

func (*UpdateQueryConstructor) AddToSet

func (qc *UpdateQueryConstructor) AddToSet(arrayFieldName string, objToAdd interface{}) *UpdateQueryConstructor

AddToSet pushes the provided interface{} object to the specified fieldname

func (*UpdateQueryConstructor) Decrement

func (qc *UpdateQueryConstructor) Decrement(fieldName string, i int) *UpdateQueryConstructor

Decrement decreases the specified field value by the provided int.

func (*UpdateQueryConstructor) Increment

func (qc *UpdateQueryConstructor) Increment(fieldName string, i int) *UpdateQueryConstructor

Increment increases the specified field value by the provided int.

func (*UpdateQueryConstructor) Match

func (qc *UpdateQueryConstructor) Match(query interface{}) *UpdateQueryConstructor

Match sets the Update query filter to the provided interface. If not specified, all documents will be updated.

func (*UpdateQueryConstructor) PopFirst

func (qc *UpdateQueryConstructor) PopFirst(arrayFieldName string) *UpdateQueryConstructor

PopFirst removes the first element from the specified array

func (*UpdateQueryConstructor) PopLast

func (qc *UpdateQueryConstructor) PopLast(arrayFieldName string) *UpdateQueryConstructor

PopLast removes the last element from the specified array

func (*UpdateQueryConstructor) Pull

func (qc *UpdateQueryConstructor) Pull(arrayFieldName string, pullCondition interface{}) *UpdateQueryConstructor

Pull pulls any array values that match the pullCondition query.

func (*UpdateQueryConstructor) PullAll

func (qc *UpdateQueryConstructor) PullAll(arrayFieldName string, pullCondition interface{}) *UpdateQueryConstructor

PullAll pulls any array values that match the pullCondition query. TODO: What is the difference between Pull and PullAll?

func (*UpdateQueryConstructor) Push

func (qc *UpdateQueryConstructor) Push(arrayFieldName string, objToPush interface{}) *UpdateQueryConstructor

Push pushes the specified object on to an array.

func (*UpdateQueryConstructor) Set

func (qc *UpdateQueryConstructor) Set(fieldName string, objToSet interface{}) *UpdateQueryConstructor

Set sets fieldName to the provided object. If you are looking to replace an entire document, consider using collection.Replace() instead. e.g. {"$set": {objToSet: objToSet}}

Jump to

Keyboard shortcuts

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