Documentation Index
Fetch the complete documentation index at: https://www.esixorm.com/llms.txt
Use this file to discover all available pages before exploring further.
Retrieving Models
Once you have your models defined, querying your database becomes incredibly straightforward! Each Esix model acts as a powerful query builder, allowing you to fluently search and retrieve documents from your MongoDB collection.
Finding a Single Record
When you need to find a specific document by its ID, use the find method:
const book = await Book.find(22)
console.log(book.title)
find accepts both ObjectId hex strings and plain string ids. If the value is
not a valid 24-character hex string, Esix transparently falls back to a string
_id lookup. Invalid input never throws — find just returns null when no
matching document exists.
You can also find a model by a specific field using the findBy method:
const user = await User.findBy('email', 'john@example.com')
console.log(user.name)
To get the first model that matches your query conditions, use the first
method:
const latestPost = await BlogPost.where('status', 'published')
.orderBy('createdAt', 'desc')
.first()
console.log(latestPost.title)
You can also get all the models in the collection.
const flights = await Flight.all()
flights.forEach((flight) => {
console.log(flight.name)
})
When you are working with multiple models, you can use methods like where
which returns an instance of a QueryBuilder. The Query Builder can be used to
filter, sort, and limit your searches.
const blogPosts = await BlogPost.where('status', 'published')
.where('categoryId', 4)
.orderBy('publishedAt', 'desc')
.limit(12)
.get()
blogPosts.forEach((post) => console.log(post.title))
Comparison Operators
The where method supports comparison operators for numeric and date comparisons, similar to Laravel’s Eloquent:
// Greater than
const adults = await User.where('age', '>', 18).get()
// Greater than or equal
const eligibleVoters = await User.where('age', '>=', 18).get()
// Less than
const youngUsers = await User.where('age', '<', 30).get()
// Less than or equal
const affordableProducts = await Product.where('price', '<=', 100).get()
// Equals (explicit)
const exactMatch = await Product.where('price', '=', 49.99).get()
// Not equals
const activeUsers = await User.where('status', '!=', 'banned').get()
const alsActive = await User.where('status', '<>', 'banned').get() // alternative syntax
You can chain multiple comparison operators together:
// Users between 18 and 65 years old
const workingAgeUsers = await User
.where('age', '>=', 18)
.where('age', '<=', 65)
.get()
// Products in a price range
const affordableProducts = await Product
.where('price', '>', 10)
.where('price', '<', 100)
.where('inStock', true)
.get()
// Posts with many views
const popularPosts = await BlogPost
.where('views', '>', 1000)
.where('status', 'published')
.orderBy('views', 'desc')
.get()
Supported Operators
| Operator | Description | Example |
|---|
= | Equals | .where('age', '=', 25) |
!= | Not equals | .where('status', '!=', 'banned') |
<> | Not equals (alternate) | .where('status', '<>', 'banned') |
> | Greater than | .where('age', '>', 18) |
>= | Greater than or equal | .where('score', '>=', 100) |
< | Less than | .where('age', '<', 65) |
<= | Less than or equal | .where('price', '<=', 50) |
Note: The two-parameter syntax where('status', 'published') is still supported for equality comparisons and remains the recommended approach for simple equality checks.
Array Queries
You can use whereIn to retrieve models where a column’s value is within a
given array:
const users = await User.whereIn('id', [1, 2, 3]).get()
Conversely, you can use whereNotIn to retrieve models where a column’s value
is not within a given array:
const users = await User.whereNotIn('id', [1, 2, 3]).get()
If you are only interested in a single attribute of a model, you can use the
pluck method to get an array of values for that attribute.
const productNames = await Product.where('category', 'lamps').pluck('name')
productNames.forEach((name) => console.log(name))
Distinct Values
Use distinct to get the unique values of a field across the current query:
const tags = await Post.where('published', true).distinct('tag')
The result is a deduplicated array of values for the field, respecting any
active where constraints.
Full-Text Search
Once your collection has a text index,
use search to run full-text queries:
const results = await Post.search('mongodb typescript').get()
If the collection has no text index, Esix surfaces a descriptive error
explaining how to create one.
The fastest way to paginate is paginate(page, perPage), which returns the
page of models alongside the metadata you need to render pagination UIs:
const { data, total, page, perPage, lastPage } = await Post
.where('published', true)
.paginate(1, 20)
For more control, you can fall back to manual offset pagination using skip
and limit:
const page = 2
const perPage = 10
const offset = (page - 1) * perPage
const products = await Product.where('category', 'electronics')
.skip(offset)
.limit(perPage)
.get()
You can find out more about the different methods available by consulting the
Esix source on GitHub.
Aggregate Functions
Once you are happy with your query, you can use the aggregate functions
available in Esix to perform calculations on the data set. The supported
aggregates are average, count, max, min, percentile, and sum.
await Product.where('category', 'lamps').average('price')
await Product.where('category', 'lamps').count()
await Product.where('category', 'lamps').max('price')
await Product.where('category', 'lamps').min('price')
await Product.where('category', 'lamps').percentile('price', 50)
await Product.where('category', 'lamps').sum('price')
When the query matches no documents, the numeric aggregates (average,
max, min, percentile, sum) return 0 rather than throwing.
percentile requires n to be a finite number between 0 and 100. Any
other value (including NaN and Infinity) throws a descriptive error so
that bad inputs do not silently return misleading results.