goose

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 14, 2026 License: MIT Imports: 11 Imported by: 0

README

Goose 🦆 (Formally MORM)

A Mongoose-inspired MongoDB ODM for Go

Go Reference Go Report Card

Goose is an elegant, type-safe MongoDB Object Document Mapper (ODM) for Go, heavily inspired by the beloved Node.js library Mongoose. Built on top of the official mongo-driver, Goose leverages Go 1.18+ Generics to provide a robust, developer-friendly API.

Features

  • Type-safe CRUD via Go Generics (Model[T])
  • Fluent Query Builder with clone-on-write chaining
  • Population ($lookup joins) via struct tags
  • Virtual fields (computed properties)
  • Schema definition & validation
  • Middleware/Hooks (interface-based + schema-level)
  • Aggregation pipeline builder
  • Transaction support
  • Plugin system
  • Automatic timestamps
  • Cursor-based iteration
  • Custom error types
  • Index management
  • Schema inheritance (discriminators)
  • Functional options for configuration
  • Context-first API (idiomatic Go)

Quick Start

Installation
go get github.com/devsamahd/goose
Complete Example
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/devsamahd/goose"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

// User represents our user document
type User struct {
	ID        primitive.ObjectID `bson:"_id,omitempty"`
	Name      string             `bson:"name" goose:"required"`
	Email     string             `bson:"email" goose:"required,unique"`
	Age       int                `bson:"age" goose:"min=18"`
	Posts     []primitive.ObjectID `bson:"posts" goose:"ref=Post"`
	CreatedAt time.Time          `bson:"createdAt"`
	UpdatedAt time.Time          `bson:"updatedAt"`
}

// Post represents our post document
type Post struct {
	ID      primitive.ObjectID `bson:"_id,omitempty"`
	Title   string             `bson:"title"`
	Content string             `bson:"content"`
	Author  primitive.ObjectID `bson:"author" goose:"ref=User"`
}

func main() {
	ctx := context.Background()

	// 1. Connect to MongoDB
	client, err := goose.Connect(ctx, "mongodb://localhost:27017", goose.WithDatabase("goose_example"))
	if err != nil {
		log.Fatal(err)
	}
	defer client.Disconnect(ctx)

	// 2. Define a Schema
	userSchema := goose.NewSchema()
	
	// Use hooks
	userSchema.PreSave(func(ctx context.Context, doc interface{}) error {
		user := doc.(*User)
		if user.CreatedAt.IsZero() {
			user.CreatedAt = time.Now()
		}
		user.UpdatedAt = time.Now()
		return nil
	})

	// 3. Create a Model
	userModel := goose.NewModel[User](client, "users", userSchema)
	postModel := goose.NewModel[Post](client, "posts", goose.NewSchema())

	// 4. Create Documents
	user := &User{
		Name:  "Jane Doe",
		Email: "jane@example.com",
		Age:   28,
	}
	
	insertRes, err := userModel.Create(ctx, user)
	if err != nil {
		log.Fatal(err)
	}
	
	post := &Post{
		Title:   "Hello World",
		Content: "My first post with Goose!",
		Author:  insertRes.InsertedID.(primitive.ObjectID),
	}
	if _, err := postModel.Create(ctx, post); err != nil {
		log.Fatal(err)
	}

	// 5. Find and Populate Documents
	var foundUser User
	err = userModel.FindOne(goose.M{"email": "jane@example.com"}).
		Populate("Posts").
		Exec(ctx, &foundUser)
		
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Found User: %s\n", foundUser.Name)
}

API Reference

Connection

Connect to MongoDB with functional options:

client, err := goose.Connect(ctx, uri, goose.WithDatabase("mydb"), goose.WithMaxPoolSize(100))
db := client.Database()
Schema & Validation

Define rules, defaults, and relations via struct tags or schema definition:

schema := goose.NewSchema()
schema.AddIndex(goose.Index{Keys: bson.D{{"email", 1}}, Unique: true})
Model[T] CRUD

Type-safe operations powered by generics:

model := goose.NewModel[MyType](client, "collection", schema)

// Create
res, err := model.Create(ctx, &doc)

// Read
var docs []MyType
err := model.Find(bson.M{"age": bson.M{"$gte": 18}}).Exec(ctx, &docs)

// Update
res, err := model.UpdateOne(ctx, bson.M{"_id": id}, bson.M{"$set": bson.M{"status": "active"}})

// Delete
res, err := model.DeleteOne(ctx, bson.M{"_id": id})
Query Builder

Fluent chaining for expressive queries:

err := model.Find(bson.M{"status": "active"}).
	Select("name", "email").
	Sort("-createdAt").
	Limit(10).
	Skip(20).
	Exec(ctx, &results)
Population

Resolve references seamlessly:

err := model.Find().
	Populate("Author").
	Populate("Comments").
	Exec(ctx, &docs)
Hooks / Middleware

Intercept lifecycle events:

schema.PreSave(func(ctx context.Context, doc any) error { ... })
schema.PostFind(func(ctx context.Context, docs []any) error { ... })
Aggregation

Build robust pipelines:

err := model.Aggregate().
	Match(bson.M{"status": "active"}).
	Group(bson.D{{"_id", "$category"}, {"count", bson.M{"$sum": 1}}}).
	Exec(ctx, &results)
Transactions

Execute operations atomically:

err := client.WithTransaction(ctx, func(sessCtx mongo.SessionContext) error {
	// perform operations using sessCtx
	return nil
})
Virtuals

Define computed properties that don't persist to the database:

schema.Virtual("FullName").Get(func(doc any) any {
	u := doc.(*User)
	return u.FirstName + " " + u.LastName
})
Plugins

Extend schema functionality globally:

func TimestampPlugin(s *goose.Schema, options any) {
	s.PreSave(func(ctx context.Context, doc any) error { ... })
}

schema.Plugin(TimestampPlugin, nil)

Contributing

Contributions are deeply appreciated! Please read our Contributing Guidelines to get started.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.


© Devsamahd, 2024

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound     = errors.New("goose: document not found")
	ErrValidation   = errors.New("goose: validation failed")
	ErrDuplicateKey = errors.New("goose: duplicate key")
	ErrInvalidID    = errors.New("goose: invalid ObjectID")
	ErrNotConnected = errors.New("goose: not connected to MongoDB")
	ErrInvalidModel = errors.New("goose: model must be a pointer to a struct")
	ErrTransaction  = errors.New("goose: transaction failed")
	ErrEmptyUpdate  = errors.New("goose: update document is empty")
)

Sentinel errors

Functions

This section is empty.

Types

type AfterCreateHook

type AfterCreateHook interface {
	AfterCreate(ctx context.Context) error
}

AfterCreateHook is called after inserting a new document.

type AfterDeleteHook

type AfterDeleteHook interface {
	AfterDelete(ctx context.Context) error
}

AfterDeleteHook is called after a delete operation.

type AfterFindHook

type AfterFindHook interface {
	AfterFind(ctx context.Context) error
}

AfterFindHook is called after a document is decoded from a query.

type AfterSaveHook

type AfterSaveHook interface {
	AfterSave(ctx context.Context) error
}

AfterSaveHook is called after any create or update.

type AfterUpdateHook

type AfterUpdateHook interface {
	AfterUpdate(ctx context.Context) error
}

AfterUpdateHook is called after an update operation.

type AggregationCursor

type AggregationCursor[T any] struct {
	// contains filtered or unexported fields
}

AggregationCursor is a chainable aggregation pipeline builder.

func (*AggregationCursor[T]) AddFields

func (a *AggregationCursor[T]) AddFields(fields interface{}) *AggregationCursor[T]

AddFields adds an $addFields stage.

func (*AggregationCursor[T]) Cursor

func (a *AggregationCursor[T]) Cursor() (*Cursor[T], error)

Cursor returns a type-safe cursor for the aggregation results.

func (*AggregationCursor[T]) Exec

func (a *AggregationCursor[T]) Exec() ([]*T, error)

Exec executes the aggregation pipeline and returns all results.

func (*AggregationCursor[T]) Group

func (a *AggregationCursor[T]) Group(group interface{}) *AggregationCursor[T]

Group adds a $group stage.

func (*AggregationCursor[T]) Limit

func (a *AggregationCursor[T]) Limit(n int64) *AggregationCursor[T]

Limit adds a $limit stage.

func (*AggregationCursor[T]) Lookup

func (a *AggregationCursor[T]) Lookup(lookup LookupStage) *AggregationCursor[T]

Lookup adds a $lookup stage.

func (*AggregationCursor[T]) Match

func (a *AggregationCursor[T]) Match(filter interface{}) *AggregationCursor[T]

Match adds a $match stage.

func (*AggregationCursor[T]) Project

func (a *AggregationCursor[T]) Project(projection interface{}) *AggregationCursor[T]

Project adds a $project stage.

func (*AggregationCursor[T]) Skip

func (a *AggregationCursor[T]) Skip(n int64) *AggregationCursor[T]

Skip adds a $skip stage.

func (*AggregationCursor[T]) Sort

func (a *AggregationCursor[T]) Sort(sort interface{}) *AggregationCursor[T]

Sort adds a $sort stage.

func (*AggregationCursor[T]) Unwind

func (a *AggregationCursor[T]) Unwind(path string) *AggregationCursor[T]

Unwind adds an $unwind stage.

type BeforeCreateHook

type BeforeCreateHook interface {
	BeforeCreate(ctx context.Context) error
}

BeforeCreateHook is called before inserting a new document.

type BeforeDeleteHook

type BeforeDeleteHook interface {
	BeforeDelete(ctx context.Context) error
}

BeforeDeleteHook is called before a delete operation.

type BeforeSaveHook

type BeforeSaveHook interface {
	BeforeSave(ctx context.Context) error
}

BeforeSaveHook is called before any create or update.

type BeforeUpdateHook

type BeforeUpdateHook interface {
	BeforeUpdate(ctx context.Context) error
}

BeforeUpdateHook is called before an update operation.

type Client

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

Client holds the MongoDB connection.

func Connect

func Connect(ctx context.Context, uri string, opts ...Option) (*Client, error)

Connect establishes a connection to MongoDB. Use functional options to configure the connection.

Example:

client, err := goose.Connect(ctx, "mongodb://localhost:27017",
	goose.WithDatabase("myapp"),
	goose.WithTimeout(10 * time.Second),
)

func (*Client) Database

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

Database returns a handle to the named database.

func (*Client) DefaultDatabase

func (c *Client) DefaultDatabase() *Database

DefaultDatabase returns a handle to the database configured via WithDatabase. Panics if no default database was configured.

func (*Client) Disconnect

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

Disconnect closes the MongoDB connection.

func (*Client) MongoClient

func (c *Client) MongoClient() *mongo.Client

MongoClient returns the underlying mongo.Client for advanced usage.

func (*Client) WithTransaction

func (c *Client) WithTransaction(ctx context.Context, fn func(sessCtx context.Context) error) error

WithTransaction executes fn within a MongoDB transaction. It automatically starts a session, begins a transaction, and: - Commits on success - Aborts on error - Handles transient transaction errors with retry

Example:

err := client.WithTransaction(ctx, func(sessCtx context.Context) error {
	_, err := orderModel.Create(sessCtx, &order)
	if err != nil { return err }
	_, err = inventoryModel.UpdateOne(sessCtx,
		bson.M{"_id": productID},
		bson.M{"$inc": bson.M{"stock": -1}},
	)
	return err
})

type Cursor

type Cursor[T any] struct {
	// contains filtered or unexported fields
}

Cursor wraps a mongo.Cursor with type-safe decoding.

func (*Cursor[T]) All

func (c *Cursor[T]) All(ctx context.Context) ([]*T, error)

All decodes all remaining documents into a slice.

func (*Cursor[T]) Close

func (c *Cursor[T]) Close(ctx context.Context) error

Close closes the cursor.

func (*Cursor[T]) Decode

func (c *Cursor[T]) Decode() (*T, error)

Decode decodes the current cursor document into a *T.

func (*Cursor[T]) Next

func (c *Cursor[T]) Next(ctx context.Context) bool

Next advances the cursor. Returns false when exhausted.

type Database

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

Database represents a MongoDB database.

func (*Database) MongoDatabase

func (d *Database) MongoDatabase() *mongo.Database

MongoDatabase returns the underlying mongo.Database for advanced usage.

type DeleteResult

type DeleteResult struct {
	DeletedCount int64
}

DeleteResult holds the result of a delete operation.

type DiscriminatorConfig

type DiscriminatorConfig struct {
	// Name is the discriminator value used to distinguish document types.
	Name string
	// Schema is the additional schema fields for this discriminator.
	Schema *Schema
}

DiscriminatorConfig holds configuration for a discriminator model.

type Document

type Document struct {
	ID        primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	CreatedAt time.Time          `bson:"createdAt,omitempty" json:"createdAt"`
	UpdatedAt time.Time          `bson:"updatedAt,omitempty" json:"updatedAt"`
}

Document provides standard MongoDB document fields. Embed this in your structs to get automatic _id and timestamp management.

Example:

type User struct {
	goose.Document `bson:",inline"`
	Name  string `bson:"name" json:"name"`
	Email string `bson:"email" json:"email"`
}

func (*Document) GetID

func (d *Document) GetID() primitive.ObjectID

GetID returns the document's ObjectID.

func (*Document) SetID

func (d *Document) SetID(id primitive.ObjectID)

SetID sets the document's ObjectID.

type FieldDef

type FieldDef struct {
	Type         FieldType
	Required     bool
	Default      interface{}
	Unique       bool
	Index        bool
	Ref          string // Collection name for population
	Enum         []interface{}
	Min          interface{} // Min value or length
	Max          interface{} // Max value or length
	Match        string      // Regex pattern for strings
	Validate     ValidatorFn // Custom validator
	LocalField   string      // For populate virtuals
	ForeignField string      // For populate virtuals
	JustOne      bool        // Single vs array for populate
	Select       *bool       // Include by default in queries (nil = true)
	Immutable    bool        // Cannot be changed after creation
	Sparse       bool        // Sparse index
	Trim         bool        // Auto-trim whitespace (strings)
	Lowercase    bool        // Auto-lowercase (strings)
	Uppercase    bool        // Auto-uppercase (strings)
}

FieldDef defines a single field in the schema.

type FieldType

type FieldType int

FieldType represents the type of a schema field.

const (
	TypeString FieldType = iota
	TypeNumber
	TypeBoolean
	TypeDate
	TypeObjectID
	TypeArray
	TypeMap
	TypeMixed
	TypeDecimal128
	TypeUUID
	TypeInt32
	TypeInt64
	TypeFloat64
)

func (FieldType) String

func (ft FieldType) String() string

String returns the string representation of a FieldType.

type HookFunc

type HookFunc func(ctx context.Context, doc interface{}) error

HookFunc is a schema-level hook function.

type HookType

type HookType string

HookType identifies the operation a hook applies to.

const (
	HookSave      HookType = "save"
	HookValidate  HookType = "validate"
	HookRemove    HookType = "remove"
	HookUpdateOne HookType = "updateOne"
	HookDeleteOne HookType = "deleteOne"
	HookFind      HookType = "find"
	HookFindOne   HookType = "findOne"
	HookCreate    HookType = "create"
)

type IndexDef

type IndexDef struct {
	Keys               interface{} // bson.D for index keys
	Name               string
	Unique             bool
	Sparse             bool
	ExpireAfterSeconds *int32
}

IndexDef defines a MongoDB index.

type LookupStage

type LookupStage struct {
	From         string
	LocalField   string
	ForeignField string
	As           string
}

LookupStage defines a $lookup aggregation stage.

type Model

type Model[T any] struct {
	// contains filtered or unexported fields
}

Model provides type-safe CRUD operations for a MongoDB collection.

func NewModel

func NewModel[T any](db *Database, collection string, schema ...*Schema) *Model[T]

NewModel creates a new Model[T] bound to a collection.

func (*Model[T]) Aggregate

func (m *Model[T]) Aggregate(ctx context.Context, pipeline ...interface{}) *AggregationCursor[T]

Aggregate starts an aggregation pipeline.

func (*Model[T]) Collection

func (m *Model[T]) Collection() *mongo.Collection

Collection returns the underlying mongo.Collection.

func (*Model[T]) CountDocuments

func (m *Model[T]) CountDocuments(ctx context.Context, filter interface{}) (int64, error)

CountDocuments counts documents matching the filter.

func (*Model[T]) Create

func (m *Model[T]) Create(ctx context.Context, doc *T) (*T, error)

Create inserts a new document and returns it with the generated ID.

func (*Model[T]) CreateIndex

func (m *Model[T]) CreateIndex(ctx context.Context, index IndexDef) (string, error)

CreateIndex creates a single index on the collection.

func (*Model[T]) CreateIndexes

func (m *Model[T]) CreateIndexes(ctx context.Context, indexes []IndexDef) ([]string, error)

CreateIndexes creates multiple indexes on the collection.

func (*Model[T]) DeleteMany

func (m *Model[T]) DeleteMany(ctx context.Context, filter interface{}) (*DeleteResult, error)

DeleteMany deletes all documents matching the filter.

func (*Model[T]) DeleteOne

func (m *Model[T]) DeleteOne(ctx context.Context, filter interface{}) (*DeleteResult, error)

DeleteOne deletes a single document matching the filter.

func (*Model[T]) Distinct

func (m *Model[T]) Distinct(ctx context.Context, field string, filter interface{}) ([]interface{}, error)

Distinct returns distinct values for the given field.

func (*Model[T]) DropIndex

func (m *Model[T]) DropIndex(ctx context.Context, name string) error

DropIndex drops an index by name.

func (*Model[T]) Exists

func (m *Model[T]) Exists(ctx context.Context, filter interface{}) (bool, error)

Exists checks whether any document matches the filter.

func (*Model[T]) Find

func (m *Model[T]) Find(ctx context.Context, filter ...interface{}) *Query[T]

Find returns a Query[T] for finding multiple documents.

func (*Model[T]) FindByID

func (m *Model[T]) FindByID(ctx context.Context, id interface{}) *Query[T]

FindByID returns a Query[T] for finding a document by its ID.

func (*Model[T]) FindByIDAndDelete

func (m *Model[T]) FindByIDAndDelete(ctx context.Context, id interface{}) (*T, error)

FindByIDAndDelete finds a document by ID, deletes it, and returns it.

func (*Model[T]) FindByIDAndUpdate

func (m *Model[T]) FindByIDAndUpdate(ctx context.Context, id, update interface{}) (*T, error)

FindByIDAndUpdate finds a document by ID, updates it, and returns the updated document.

func (*Model[T]) FindOne

func (m *Model[T]) FindOne(ctx context.Context, filter interface{}) *Query[T]

FindOne returns a Query[T] for finding a single document.

func (*Model[T]) FindOneAndDelete

func (m *Model[T]) FindOneAndDelete(ctx context.Context, filter interface{}) (*T, error)

FindOneAndDelete finds a document, deletes it, and returns the deleted document.

func (*Model[T]) FindOneAndUpdate

func (m *Model[T]) FindOneAndUpdate(ctx context.Context, filter, update interface{}) (*T, error)

FindOneAndUpdate finds a document, updates it, and returns the updated document.

func (*Model[T]) InsertMany

func (m *Model[T]) InsertMany(ctx context.Context, docs []*T) ([]*T, error)

InsertMany inserts multiple documents.

func (*Model[T]) ReplaceOne

func (m *Model[T]) ReplaceOne(ctx context.Context, filter interface{}, replacement *T) (*UpdateResult, error)

ReplaceOne replaces a single document matching the filter.

func (*Model[T]) UpdateMany

func (m *Model[T]) UpdateMany(ctx context.Context, filter, update interface{}) (*UpdateResult, error)

UpdateMany updates all documents matching the filter.

func (*Model[T]) UpdateOne

func (m *Model[T]) UpdateOne(ctx context.Context, filter, update interface{}) (*UpdateResult, error)

UpdateOne updates a single document matching the filter.

type Option

type Option func(*config)

Option configures a Client.

func WithDatabase

func WithDatabase(name string) Option

WithDatabase sets the default database name.

func WithMaxPoolSize

func WithMaxPoolSize(size uint64) Option

WithMaxPoolSize sets the maximum connection pool size.

func WithMinPoolSize

func WithMinPoolSize(size uint64) Option

WithMinPoolSize sets the minimum connection pool size.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the connection/operation timeout.

type Plugin

type Plugin func(schema *Schema, opts interface{})

Plugin is a function that extends a schema with additional behavior. Plugins can add fields, hooks, methods, virtuals, or indexes to a schema.

Example:

// Soft delete plugin
func SoftDeletePlugin(s *goose.Schema, opts interface{}) {
	s.Pre(goose.HookDeleteOne, func(ctx context.Context, doc interface{}) error {
		// Convert delete to soft delete
		return nil
	})
}

type PopulateOption

type PopulateOption struct {
	Path     string           // Field path to populate
	Model    string           // Target collection (auto-inferred from schema Ref if omitted)
	Select   []string         // Fields to include from populated doc
	Match    interface{}      // Additional filter for populated docs
	Populate []PopulateOption // Nested population
}

PopulateOption configures a population (join) operation.

type Query

type Query[T any] struct {
	// contains filtered or unexported fields
}

Query is a chainable, immutable query builder.

func (*Query[T]) All

func (q *Query[T]) All() ([]*T, error)

All executes a find query and returns all matching documents.

func (*Query[T]) Count

func (q *Query[T]) Count() (int64, error)

Count returns the number of documents matching the query.

func (*Query[T]) Cursor

func (q *Query[T]) Cursor() (*Cursor[T], error)

Cursor returns a type-safe cursor for iterating over results.

func (*Query[T]) Exec

func (q *Query[T]) Exec() (*T, error)

Exec executes the query and returns a single result (for findone queries).

func (*Query[T]) Lean

func (q *Query[T]) Lean() *Query[T]

Lean returns plain results without full model hydration.

func (*Query[T]) Limit

func (q *Query[T]) Limit(n int64) *Query[T]

Limit sets the maximum number of documents.

func (*Query[T]) Populate

func (q *Query[T]) Populate(fields ...string) *Query[T]

Populate specifies fields to populate via $lookup.

func (*Query[T]) Select

func (q *Query[T]) Select(fields ...string) *Query[T]

Select sets field projection. Fields prefixed with "-" are excluded.

func (*Query[T]) Skip

func (q *Query[T]) Skip(n int64) *Query[T]

Skip sets the number of documents to skip.

func (*Query[T]) Sort

func (q *Query[T]) Sort(field string, order int) *Query[T]

Sort adds a sort field. Order: 1 ascending, -1 descending.

func (*Query[T]) SortBy

func (q *Query[T]) SortBy(sorts bson.D) *Query[T]

SortBy sets sort criteria from a bson.D.

type Schema

type Schema struct {
	Fields    map[string]FieldDef
	Options   SchemaOptions
	Virtuals  map[string]VirtualDef
	PreHooks  map[HookType][]HookFunc
	PostHooks map[HookType][]HookFunc
	Indexes   []IndexDef
	Plugins   []pluginEntry
}

Schema defines the structure, validation rules, and behavior of a model.

func MergeSchemas

func MergeSchemas(parent, child *Schema) *Schema

MergeSchemas creates a new schema by merging a parent schema with a child schema. The child schema's fields are added to/override the parent's fields. Both schemas' hooks, virtuals, and plugins are combined.

func NewSchema

func NewSchema(fields map[string]FieldDef, opts ...SchemaOption) *Schema

NewSchema creates a new Schema with the given field definitions and options.

func (*Schema) AddIndex

func (s *Schema) AddIndex(index IndexDef) *Schema

AddIndex adds an index definition to the schema. Returns the schema for chaining.

func (*Schema) AddVirtual

func (s *Schema) AddVirtual(name string, def VirtualDef) *Schema

AddVirtual registers a virtual field on the schema. Virtual fields are computed on read and are not stored in MongoDB.

Example:

schema.AddVirtual("fullName", goose.VirtualDef{
	Get: func(doc interface{}) interface{} {
		u := doc.(*User)
		return u.FirstName + " " + u.LastName
	},
})

func (*Schema) ApplyVirtuals

func (s *Schema) ApplyVirtuals(doc interface{}) map[string]interface{}

ApplyVirtuals computes all virtual fields for a document and returns them as a map.

func (*Schema) GetVirtual

func (s *Schema) GetVirtual(name string, doc interface{}) (interface{}, bool)

GetVirtual retrieves a virtual field value for the given document.

func (*Schema) Post

func (s *Schema) Post(hook HookType, fn HookFunc) *Schema

Post registers a post-hook on the schema. Returns the schema for chaining.

func (*Schema) Pre

func (s *Schema) Pre(hook HookType, fn HookFunc) *Schema

Pre registers a pre-hook on the schema. Returns the schema for chaining.

func (*Schema) SetVirtual

func (s *Schema) SetVirtual(name string, doc interface{}, val interface{}) bool

SetVirtual sets a virtual field value on the given document.

func (*Schema) Use

func (s *Schema) Use(plugin Plugin, opts ...interface{}) *Schema

Use applies a plugin to the schema. Returns the schema for chaining.

type SchemaOption

type SchemaOption func(*SchemaOptions)

SchemaOption configures schema creation.

func WithCollection

func WithCollection(name string) SchemaOption

WithCollection sets a custom collection name for the schema.

func WithDiscriminatorKey

func WithDiscriminatorKey(key string) SchemaOption

WithDiscriminatorKey sets the discriminator key for schema inheritance.

func WithStrict

func WithStrict(b bool) SchemaOption

WithStrict configures strict mode, whether to reject fields not defined in the schema.

func WithTimestamps

func WithTimestamps(b bool) SchemaOption

WithTimestamps configures whether to auto-manage createdAt/updatedAt timestamps.

func WithVersionKey

func WithVersionKey(b bool) SchemaOption

WithVersionKey configures whether to use the __v versioning key.

type SchemaOptions

type SchemaOptions struct {
	Timestamps       bool   // Auto-manage createdAt/updatedAt
	Collection       string // Override collection name
	DiscriminatorKey string // Discriminator key for inheritance
	Strict           bool   // Reject fields not in schema (default: true)
	VersionKey       bool   // Enable __v versioning
}

SchemaOptions configures schema-level behavior.

type UpdateResult

type UpdateResult struct {
	MatchedCount  int64
	ModifiedCount int64
	UpsertedCount int64
	UpsertedID    interface{}
}

UpdateResult holds the result of an update operation.

type ValidationError

type ValidationError struct {
	Field   string
	Message string
	Value   interface{}
	Kind    string // "required", "min", "max", "enum", "match", "custom"
}

ValidationError represents a single field validation failure.

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error returns the error message.

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Unwrap allows standard errors.Is/As to work with ErrValidation.

type ValidationErrors

type ValidationErrors struct {
	Errors []ValidationError
}

ValidationErrors aggregates multiple validation failures.

func (*ValidationErrors) Error

func (e *ValidationErrors) Error() string

Error returns a joined string of all validation errors.

func (*ValidationErrors) Unwrap

func (e *ValidationErrors) Unwrap() error

Unwrap allows standard errors.Is/As to work with ErrValidation.

type ValidatorFn

type ValidatorFn func(value interface{}) error

ValidatorFn is a function that validates a value. It should return nil if the value is valid, or an error describing the failure.

func Enum

func Enum(values ...interface{}) ValidatorFn

Enum returns a validator that checks if value is in the allowed set.

func Match

func Match(pattern string) ValidatorFn

Match returns a validator that checks if a string matches a regex pattern.

func Max

func Max(n float64) ValidatorFn

Max returns a validator for maximum numeric value.

func MaxLength

func MaxLength(n int) ValidatorFn

MaxLength returns a validator for maximum string length.

func Min

func Min(n float64) ValidatorFn

Min returns a validator for minimum numeric value.

func MinLength

func MinLength(n int) ValidatorFn

MinLength returns a validator for minimum string length.

func Required

func Required(fieldName string) ValidatorFn

Required returns a validator that checks a value is non-zero/non-nil/non-empty.

type VirtualDef

type VirtualDef struct {
	// Get computes the virtual field value from the document.
	Get func(doc interface{}) interface{}
	// Set applies a value to the document (optional).
	Set func(doc interface{}, val interface{})
}

VirtualDef defines a virtual (computed) field that is not persisted to MongoDB.

Jump to

Keyboard shortcuts

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