Ordering
Ordering query results by embedded object sub-fields — nested field sorting and generated OrderBy types.
You can sort query results by fields within embedded objects. Cerial translates nested ordering into dot-notation ORDER BY clauses automatically.
All examples use this schema:
object Address {
street String
city String
state String
zipCode String?
}
object GeoPoint {
lat Float
lng Float
label String?
}
model User {
id Record @id
name String
address Address
shipping Address?
locations GeoPoint[]
}Basic Ordering
Pass an object with the nested field and direction ('asc' or 'desc'):
const users = await client.db.User.findMany({
orderBy: { address: { city: 'asc' } },
});const users = await client.db.User.findMany({
orderBy: { address: { state: 'desc' } },
});Generated OrderBy Types
For each object type, Cerial generates a corresponding ObjectNameOrderBy type. This type mirrors the object's field structure, with each leaf field accepting 'asc' | 'desc':
// Generated from the Address object:
type AddressOrderBy = {
street?: 'asc' | 'desc';
city?: 'asc' | 'desc';
state?: 'asc' | 'desc';
zipCode?: 'asc' | 'desc';
};On the model side, the UserOrderBy type includes the nested object ordering:
type UserOrderBy = {
name?: 'asc' | 'desc';
address?: AddressOrderBy;
shipping?: AddressOrderBy;
// ...
};This gives you full type safety — you can only order by fields that exist in the object definition.
Combining Top-Level and Nested Field Ordering
You can combine top-level and nested field ordering in a single query:
const users = await client.db.User.findMany({
orderBy: {
address: { state: 'asc' },
},
});// Multiple ordering criteria
const users = await client.db.User.findMany({
orderBy: [
{ address: { state: 'asc' } },
{ name: 'desc' },
],
});For general orderBy usage including limit and offset for pagination, see Queries.