Skip to content

Query Builder ​

Arkorm query builder is fluent, typed, and delegate-backed.

For multi-step write flows that need atomic commit/rollback behavior, see Transactions.

Common reads ​

ts
await User.query().get()
await User.query().first()
await User.query().firstOrFail()
await User.query().find(1)

Filtering ​

ts
await User.query()
  .whereKey('isActive', true)
  .orWhere({ role: 'admin' })
  .whereNotNull('email')
  .whereIn('id', [1, 2, 3])
  .get()

Date and range helpers ​

ts
await User.query().whereBetween('id', [10, 100]).get()
await User.query().whereDate('createdAt', '2026-03-01').get()
await User.query().whereMonth('createdAt', 3, 2026).get()
await User.query().whereYear('createdAt', 2026).get()

Ordering and pagination helpers ​

ts
await User.query().latest().limit(10).get()
await User.query().oldest('updatedAt').offset(20).take(10).get()
await User.query().forPage(2, 15).get()

Existence and aggregates ​

ts
await User.query().exists()
await User.query().doesntExist()
await User.query().count()
await User.query().sum('score')
await User.query().avg('score')

Utility helpers ​

ts
await User.query().pluck('email')
await User.query().value('email')
await User.query().valueOrFail('email')

Write helpers (insert/update/upsert) ​

ts
await User.query().insert({
  id: 3,
  name: 'Alice',
  email: '[email protected]',
  isActive: true,
  createdAt: new Date(),
  updatedAt: new Date(),
})

await User.query().insert([
  {
    id: 4,
    name: 'Bob',
    email: '[email protected]',
    isActive: true,
    createdAt: new Date(),
    updatedAt: new Date(),
  },
  {
    id: 5,
    name: 'Carol',
    email: '[email protected]',
    isActive: false,
    createdAt: new Date(),
    updatedAt: new Date(),
  },
])

await User.query().insertOrIgnore([
  {
    id: 6,
    name: 'Dylan',
    email: '[email protected]',
    isActive: true,
    createdAt: new Date(),
    updatedAt: new Date(),
  },
])

const id = await User.query().insertGetId({
  id: 7,
  name: 'Eve',
  email: '[email protected]',
  isActive: true,
  createdAt: new Date(),
  updatedAt: new Date(),
})

await User.query().insertUsing(
  ['id', 'name', 'email', 'isActive', 'createdAt', 'updatedAt'],
  async () => [
    {
      id: 8,
      name: 'Frank',
      email: '[email protected]',
      isActive: true,
      createdAt: new Date(),
      updatedAt: new Date(),
    },
  ],
)

await User.query().insertOrIgnoreUsing(
  ['id', 'name', 'email', 'isActive', 'createdAt', 'updatedAt'],
  [
    {
      id: 9,
      name: 'Grace',
      email: '[email protected]',
      isActive: false,
      createdAt: new Date(),
      updatedAt: new Date(),
    },
  ],
)

await User.query().where({ email: '[email protected]' }).updateFrom({ name: 'Jane Updated' })

await User.query().updateOrInsert(
  { email: '[email protected]' },
  {
    id: 10,
    name: 'New User',
    isActive: true,
    createdAt: new Date(),
    updatedAt: new Date(),
  },
)

await User.query().upsert(
  [
    {
      id: 11,
      email: '[email protected]',
      name: 'Jane Upserted',
      isActive: true,
      createdAt: new Date(),
      updatedAt: new Date(),
    },
  ],
  'email',
  ['name'],
)
  • insert(values) inserts one or many rows.
  • insertOrIgnore(values) inserts and ignores duplicate/conflict errors when supported.
  • insertGetId(values, sequence?) inserts one row and returns the generated key field (defaults to id).
  • insertUsing(columns, query) and insertOrIgnoreUsing(columns, query) accept arrays, async resolvers, or query-builder sources.
  • updateFrom(values) performs constrained updates and returns affected count when supported by the adapter.
  • updateOrInsert(attributes, values) updates the matching record or inserts a new one.
  • upsert(values, uniqueBy, update?) processes batch upserts keyed by one or many unique columns.

Conditional composition ​

ts
await User.query()
  .when(filters.active, (q) => q.whereKey('isActive', true))
  .unless(filters.includeGuests, (q) => q.whereNot({ role: 'guest' }))
  .get()