Back to

Package entity

Latest Go to latest
Published: Mar 12, 2020 | License: MIT | Module:


Package entity defines a convenient abstraction which can be used with MongoDB in order to streamline CRUD operations.

This definition also allows a centralization of security and other policies related to an entity within the app. This leads to fewer bugs, and when there are bugs, due to the modularization of policies, the origin of bugs is easier to locate.

The goal is to define an abstraction which is useful for the general entity and can make the process of writing code much more efficient.

Axis Policy

An axis is defined as a eField in an Entity which can be assumed to be unique. This is important when creating collection indexes and creating Query/Update/Delete filters. The Axis Policy ensures data integrity by enforcing that all Entities within a collection have unique axis values.

This Policy is especially useful when querying elements for Read/Update/Delete operations. The client benefits through the ability to specify whether a eField is an axis, using the "axis" tag, in the struct eField. This tag can be set to "true" to enforce it as an axis eField.

Getting started

To use the Entity abstraction, start by creating a struct which will define the Entity that you want to work with. Available in this step, is the "axis" tag which is useful in specifying which fields are to be treated as axis fields. For example, here is a hypothetical struct for defining a (useless) User Entity:

type User struct {
	ID    primitive.ObjectID `_id_:"user" json:"-" bson:"_id"`
	Name  string             `json:"name" _hd_:"c"`
	Email string             `json:"email" axis:"true" index:"text" _hd_:"c"`

Next, register this User struct as an Entity.

UserEntity := Entity{
	SchemaDefinition: TypeOf(User{}),
	PStorage:         &mongoCollection

Run the Optimize function to generate indexes for the axis fields:


Create a User:

u := User{
	Name:  "Jane Doe",
	Email: ""

Add this user to the database:

id, err := UserEntity.Add(u)

The other Read/Update/Delete operations become as simple with this Entity definition and can lead to hundreds of lines of less code being written. The Entity package aims to (at least) provide a high level API with the basic CRUD boilerplate code already taken care of.

See for information about the EntityMux which is able to manage a collection of entities for larger applications.


Package Files

func Filter

func Filter(entity interface{}) bson.M

Filter uses the axis tags in a struct eField to create a BSON map which can be used to filter out an entity from a collection.

The filter eField is chosen with the following priority: BSON tag "_id", Axis tag "true" (then BSON, JSON tags) and lastly the eField name.

Note that the eField with the BSON tag "_id" must be of type primitive.ObjectID so that comparison succeeds.

func ToBSON

func ToBSON(entity interface{}) bson.M

ToBSON returns a BSON map representing the given entity. The given entity is expected to be of struct kind.

When converting, to BSON, eField names are selected with the following priority: BSON tag, JSON tag, eField name from the struct.

func TypeOf

func TypeOf(entity interface{}) reflect.Type

TypeOf returns an EntityDefinition which can be used with an Entity to define a schema. It performs a check to ensure that the entity is of kind struct.

type Entity

type Entity struct {
		SchemaDefinition is the base type which will be
		used for this collection.
	SchemaDefinition reflect.Type
		PStorage is the collection in which the Entities
		should be maintained.
	PStorage *mongo.Collection

Entity is a type which is used to store information about a collection of entities. It is used to manage Entities and ensure persistence.

The SchemaDefinition eField's contents is used to generate a validator for the collection. This is done using "validate" tags which allow deeper schema specification.

func (*Entity) Add

func (e *Entity) Add(entity interface{}) (primitive.ObjectID, error)

Add adds the given entity to the Entity e. The given entity is expected to be of struct kind.

This addition represents an actual insertion to the underlying database collection pointed at by e.

The added document's database ID is then returned, or any entityErrors that occurred.

func (*Entity) Delete

func (e *Entity) Delete(entity interface{}) error

Delete deletes the given entity from the underlying database collection pointed at by e.

It returns an error from the delete operation which, if all went well, can be expected to be nil.

func (*Entity) Edit

func (e *Entity) Edit(entity interface{}, spec spec.ESpec) error

Edit uses the axes of the given entity to find a document in the underlying database collection pointed at by e and edits it according to the specified spec.

An error is returned which, if all went alright, should be expected to be nil.

func (*Entity) Exists

func (e *Entity) Exists(entity, dest interface{}) (bool, error)

Exists returns whether the filter produced by the given entity matches any documents in the underlying database collection pointed at by e. If any documents are matched and dest is non-nil, the matched document will be decoded into dest, after which the fields can be accessed. If dest is left nil, the result is not decoded.

An error is also returned which, if all went alright, should be expected to be nil.

func (*Entity) Optimize

func (e *Entity) Optimize() error

Optimize is a function that creates indexes for the axis fields in the underlying EntityDefinition type.

Optimize searches for "index" tags in the fields of the type underlying the EntityDefinition. A eField with with an "index" tag is optimized. The IndexModel entry for this eField has the Key corresponding to the BSON/JSON/eField name (in that priority) and value corresponding to the "index" tag value if non-empty and a default index type of "text".

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier