Skip to content

Queries

goose provides a fluent, chainable Query builder for constructing complex MongoDB queries easily.

The Query Builder

When you call model.Find(), model.FindOne(), or model.FindByID(), goose returns a *Query[T].

Clone-on-Write

The Query builder is immutable and uses a clone-on-write mechanism. Every time you call a method like .Limit() or .Sort(), a new copy of the query is returned. This makes it safe to re-use base queries!

baseQuery := userModel.Find(ctx, bson.M{"status": "active"})

// Safe to chain differently
pagedQuery1 := baseQuery.Skip(0).Limit(10)
pagedQuery2 := baseQuery.Skip(10).Limit(10)

Chaining Methods

Sorting

// 1 for ascending, -1 for descending
query = query.Sort("createdAt", -1)

// Or using bson.D
query = query.SortBy(bson.D{{"age", 1}, {"name", -1}})

Pagination

query = query.Skip(20).Limit(10)

Projections

Select which fields to include or exclude. Prefixing a field with - excludes it.

// Include only name and email
query = query.Select("name", "email")

// Exclude password
query = query.Select("-password")

Execution

To run the query and get results:

  • .Exec(): Returns a single *T.
  • .All(): Returns a slice []*T.
  • .Count(): Returns an int64 count of matching documents.
  • .Cursor(): Returns a *goose.Cursor[T] for efficient iteration over large datasets.
count, err := query.Count()