Documentation Index
Fetch the complete documentation index at: https://woltz.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Ordering
Basic Ordering
Sort results by one or more fields:
const criteria = Criteria.create<User>()
.orderBy("name", "asc") // Ascending (A-Z)
.orderByDesc("createdAt"); // Descending (newest first)
Order Methods
// Generic method with direction
criteria.orderBy("field", "asc"); // or "desc"
// Shorthand methods
criteria.orderByAsc("name"); // Ascending
criteria.orderByDesc("createdAt"); // Descending
Multiple Orders
Orders are applied in the sequence they’re added:
const criteria = Criteria.create<Product>()
.orderByDesc("featured") // First: featured items first
.orderByAsc("price") // Then: lowest price
.orderByDesc("rating"); // Finally: highest rating
// SQL equivalent:
// ORDER BY featured DESC, price ASC, rating DESC
Ordering Nested Fields
Sort by nested object properties:
interface User {
id: string;
name: string;
profile: {
reputation: number;
joinedAt: Date;
};
}
const criteria = Criteria.create<User>()
.orderByDesc("profile.reputation")
.orderByAsc("profile.joinedAt");
Type-Safe Ordering
Only valid field paths are allowed:
const criteria = Criteria.create<User>()
.orderBy("name", "asc") // ✅ Valid
.orderBy("profile.bio", "desc") // ✅ Valid nested path
.orderBy("invalid", "asc"); // ❌ TypeScript error
const criteria = Criteria.create<User>()
.paginate(1, 20); // Page 1, 20 items per page
const criteria = Criteria.create<User>()
.paginate(3, 10); // Page 3, 10 items per page (offset: 20)
Limit Only
When you just want to limit results without full pagination:
const criteria = Criteria.create<User>()
.limit(5); // First 5 results
// Equivalent to:
criteria.paginate(1, 5);
Criteria has default pagination to prevent unbounded queries:
const criteria = Criteria.create<User>();
const pagination = criteria.getPagination();
// { page: 1, limit: 20, offset: 0 }
The getPagination() method returns:
interface Pagination {
page: number; // Current page (1-based)
limit: number; // Items per page
offset: number; // Calculated offset for SQL
}
const criteria = Criteria.create<User>()
.paginate(3, 25);
criteria.getPagination();
// { page: 3, limit: 25, offset: 50 }
const criteria = Criteria.create<User>()
.paginate(1, 20);
criteria.hasPagination(); // true (always true due to defaults)
Search
Multi-Field Search
Search across multiple fields with a single query:
const criteria = Criteria.create<User>()
.search("john");
// Matches users where:
// name contains "john" OR email contains "john" OR bio contains "john"
Search with Other Filters
Combine search with regular filters:
const criteria = Criteria.create<Product>()
.whereEquals("status", "active")
.whereEquals("categoryId", "electronics")
.search("laptop")
.orderByDesc("relevance")
.paginate(1, 20);
Checking Search State
const criteria = Criteria.create<User>()
.search("john");
criteria.hasSearch(); // true
const search = criteria.getSearch();
// "john"
Search Behavior
When search is applied with PaginatedResult.fromArray(), it:
- Searches across all items (ignoring pagination initially)
- Returns matching items
- Updates the total count based on matches
- Then applies pagination to the filtered results
// 1000 users in database
const criteria = Criteria.create<User>()
.search("john")
.paginate(1, 10);
const result = PaginatedResult.fromArray(users, criteria);
// result.meta.total = 50 (only matching users)
// result.data.length = 10 (first page of matches)
Combining Everything
Full Query Example
const criteria = Criteria.create<Product>()
// Filters
.whereEquals("status", "published")
.where("price", "lessThanOrEqual", 100)
.whereIn("category", ["electronics", "accessories"])
.whereNotNull("stock")
// Search
.search(searchQuery)
// Ordering
.orderByDesc("featured")
.orderByAsc("price")
// Pagination
.paginate(page, 24);
Dynamic Query Building
function buildProductQuery(filters: ProductFilters): Criteria<Product> {
let criteria = Criteria.create<Product>()
.whereEquals("status", "active");
// Conditional filters
if (filters.category) {
criteria = criteria.whereEquals("category", filters.category);
}
if (filters.minPrice !== undefined) {
criteria = criteria.where("price", "greaterThanOrEqual", filters.minPrice);
}
if (filters.maxPrice !== undefined) {
criteria = criteria.where("price", "lessThanOrEqual", filters.maxPrice);
}
if (filters.inStock) {
criteria = criteria.where("stock", "greaterThan", 0);
}
// Search
if (filters.query) {
criteria = criteria.search(filters.query);
}
// Ordering
switch (filters.sortBy) {
case "price-asc":
criteria = criteria.orderByAsc("price");
break;
case "price-desc":
criteria = criteria.orderByDesc("price");
break;
case "newest":
criteria = criteria.orderByDesc("createdAt");
break;
case "popular":
criteria = criteria.orderByDesc("salesCount");
break;
default:
criteria = criteria.orderByDesc("featured").orderByDesc("createdAt");
}
// Pagination
criteria = criteria.paginate(filters.page || 1, filters.perPage || 24);
return criteria;
}
const criteria = Criteria.create<User>()
.orderByDesc("createdAt")
.orderByAsc("name");
const orders = criteria.getOrders();
// [
// { field: "createdAt", direction: "desc" },
// { field: "name", direction: "asc" }
// ]
criteria.hasOrders(); // true
Order Interface
interface Order {
field: string;
direction: "asc" | "desc";
}
type OrderDirection = "asc" | "desc";
API in Query Params
Ordering via Query Params
const criteria = Criteria.fromQueryParams<Product>({
orderBy: ["price:asc", "createdAt:desc"],
});
// Creates orders:
// 1. price ASC
// 2. createdAt DESC
const criteria = Criteria.fromQueryParams<Product>({
pagination: { page: 2, limit: 20 },
});
criteria.getPagination();
// { page: 2, limit: 20, offset: 20 }
Search via Query Params
// URL: /products?search=laptop
const criteria = Criteria.fromQueryParams<Product>({
search: "laptop",
});
Complete URL Example
const criteria = Criteria.fromQueryParams<Product>({
filters: {
"status:equals": "active",
"price:lessThan": "100",
},
search: "laptop",
orderBy: ["price:asc"],
pagination: { page: 1, limit: 20 },
});