or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

associations.mddata-types.mddatabase-connection.mderror-handling.mdhooks.mdindex.mdmodel-definition.mdquery-operators.mdquerying.mdtransactions.md

query-operators.mddocs/

0

# Query Operators

1

2

Advanced query operators for complex WHERE clauses and raw SQL execution for custom database operations.

3

4

## Capabilities

5

6

### Comparison Operators

7

8

Basic comparison operators for WHERE clauses.

9

10

```typescript { .api }

11

interface OpTypes {

12

/** Equals (=) */

13

eq: symbol;

14

/** Not equals (!=) */

15

ne: symbol;

16

/** Greater than (>) */

17

gt: symbol;

18

/** Greater than or equal (>=) */

19

gte: symbol;

20

/** Less than (<) */

21

lt: symbol;

22

/** Less than or equal (<=) */

23

lte: symbol;

24

/** IS (for null checks) */

25

is: symbol;

26

/** NOT */

27

not: symbol;

28

/** BETWEEN */

29

between: symbol;

30

/** NOT BETWEEN */

31

notBetween: symbol;

32

/** IN */

33

in: symbol;

34

/** NOT IN */

35

notIn: symbol;

36

}

37

38

const Op: OpTypes;

39

```

40

41

**Usage Examples:**

42

43

```typescript

44

import { Op } from "sequelize";

45

46

// Equals

47

const users = await User.findAll({

48

where: {

49

age: { [Op.eq]: 25 }

50

// Or simply: age: 25

51

}

52

});

53

54

// Not equals

55

const users = await User.findAll({

56

where: {

57

status: { [Op.ne]: 'inactive' }

58

}

59

});

60

61

// Greater than / Less than

62

const users = await User.findAll({

63

where: {

64

age: { [Op.gt]: 18 },

65

salary: { [Op.lte]: 50000 }

66

}

67

});

68

69

// Between

70

const users = await User.findAll({

71

where: {

72

age: { [Op.between]: [18, 65] },

73

salary: { [Op.notBetween]: [30000, 40000] }

74

}

75

});

76

77

// In / Not In

78

const users = await User.findAll({

79

where: {

80

role: { [Op.in]: ['admin', 'moderator'] },

81

status: { [Op.notIn]: ['banned', 'suspended'] }

82

}

83

});

84

85

// IS / NOT (for null values)

86

const users = await User.findAll({

87

where: {

88

deletedAt: { [Op.is]: null },

89

profilePicture: { [Op.not]: null }

90

}

91

});

92

```

93

94

### String Operators

95

96

Operators for string pattern matching and text search.

97

98

```typescript { .api }

99

interface OpTypes {

100

/** LIKE */

101

like: symbol;

102

/** NOT LIKE */

103

notLike: symbol;

104

/** ILIKE (case insensitive, PostgreSQL) */

105

iLike: symbol;

106

/** NOT ILIKE */

107

notILike: symbol;

108

/** LIKE 'value%' */

109

startsWith: symbol;

110

/** LIKE '%value' */

111

endsWith: symbol;

112

/** LIKE '%value%' */

113

substring: symbol;

114

/** REGEXP (MySQL/PostgreSQL) */

115

regexp: symbol;

116

/** NOT REGEXP */

117

notRegexp: symbol;

118

/** ~* (case insensitive regexp, PostgreSQL) */

119

iRegexp: symbol;

120

/** !~* (case insensitive not regexp, PostgreSQL) */

121

notIRegexp: symbol;

122

}

123

```

124

125

**Usage Examples:**

126

127

```typescript

128

// LIKE patterns

129

const users = await User.findAll({

130

where: {

131

firstName: { [Op.like]: 'John%' }, // Starts with "John"

132

lastName: { [Op.notLike]: '%test%' }, // Doesn't contain "test"

133

email: { [Op.iLike]: '%@COMPANY.COM' } // Case insensitive (PostgreSQL)

134

}

135

});

136

137

// Convenience string operators

138

const users = await User.findAll({

139

where: {

140

firstName: { [Op.startsWith]: 'John' }, // LIKE 'John%'

141

lastName: { [Op.endsWith]: 'son' }, // LIKE '%son'

142

bio: { [Op.substring]: 'developer' } // LIKE '%developer%'

143

}

144

});

145

146

// Regular expressions

147

const users = await User.findAll({

148

where: {

149

phone: { [Op.regexp]: '^\\d{3}-\\d{3}-\\d{4}$' }, // MySQL/PostgreSQL

150

username: { [Op.iRegexp]: '^[a-z]+$' } // PostgreSQL only

151

}

152

});

153

```

154

155

### Logical Operators

156

157

Operators for combining multiple conditions.

158

159

```typescript { .api }

160

interface OpTypes {

161

/** AND */

162

and: symbol;

163

/** OR */

164

or: symbol;

165

}

166

```

167

168

**Usage Examples:**

169

170

```typescript

171

// AND (implicit by default)

172

const users = await User.findAll({

173

where: {

174

age: { [Op.gte]: 18 },

175

isActive: true

176

// Implicit AND between conditions

177

}

178

});

179

180

// Explicit AND

181

const users = await User.findAll({

182

where: {

183

[Op.and]: [

184

{ age: { [Op.gte]: 18 } },

185

{ isActive: true }

186

]

187

}

188

});

189

190

// OR

191

const users = await User.findAll({

192

where: {

193

[Op.or]: [

194

{ firstName: 'John' },

195

{ lastName: 'Doe' }

196

]

197

}

198

});

199

200

// Complex combinations

201

const users = await User.findAll({

202

where: {

203

[Op.and]: [

204

{ isActive: true },

205

{

206

[Op.or]: [

207

{ role: 'admin' },

208

{

209

[Op.and]: [

210

{ role: 'user' },

211

{ verified: true }

212

]

213

}

214

]

215

}

216

]

217

}

218

});

219

```

220

221

### Array Operators

222

223

Operators for array operations (PostgreSQL primarily).

224

225

```typescript { .api }

226

interface OpTypes {

227

/** @> (array contains) */

228

contains: symbol;

229

/** <@ (array contained by) */

230

contained: symbol;

231

/** && (array overlap) */

232

overlap: symbol;

233

/** ANY */

234

any: symbol;

235

/** ALL */

236

all: symbol;

237

}

238

```

239

240

**Usage Examples:**

241

242

```typescript

243

// PostgreSQL array operations

244

const users = await User.findAll({

245

where: {

246

tags: { [Op.contains]: ['developer', 'javascript'] }, // Array contains values

247

skills: { [Op.contained]: ['js', 'node', 'react'] }, // Array is subset

248

interests: { [Op.overlap]: ['music', 'sports'] } // Arrays have common elements

249

}

250

});

251

252

// ANY operator

253

const users = await User.findAll({

254

where: {

255

age: { [Op.gt]: { [Op.any]: [18, 21, 25] } } // age > ANY(18,21,25)

256

}

257

});

258

259

// ALL operator

260

const users = await User.findAll({

261

where: {

262

score: { [Op.gt]: { [Op.all]: [80, 85, 90] } } // score > ALL(80,85,90)

263

}

264

});

265

```

266

267

### Range Operators

268

269

Operators for range types (PostgreSQL).

270

271

```typescript { .api }

272

interface OpTypes {

273

/** -|- (adjacent ranges) */

274

adjacent: symbol;

275

/** << (strictly left of) */

276

strictLeft: symbol;

277

/** >> (strictly right of) */

278

strictRight: symbol;

279

/** &< (does not extend right of) */

280

noExtendRight: symbol;

281

/** &> (does not extend left of) */

282

noExtendLeft: symbol;

283

}

284

```

285

286

**Usage Example:**

287

288

```typescript

289

// PostgreSQL range operations

290

const events = await Event.findAll({

291

where: {

292

dateRange: { [Op.overlap]: '[2023-01-01,2023-12-31)' },

293

timeSlot: { [Op.adjacent]: '[09:00,10:00)' }

294

}

295

});

296

```

297

298

### Special Operators

299

300

Special operators for advanced use cases.

301

302

```typescript { .api }

303

interface OpTypes {

304

/** Column reference */

305

col: symbol;

306

/** @@ (full text search, PostgreSQL) */

307

match: symbol;

308

/** VALUES clause */

309

values: symbol;

310

/** Internal placeholder */

311

placeholder: symbol;

312

}

313

```

314

315

**Usage Examples:**

316

317

```typescript

318

// Column references

319

const users = await User.findAll({

320

where: {

321

firstName: { [Op.col]: 'lastName' } // WHERE firstName = lastName

322

}

323

});

324

325

// Full text search (PostgreSQL)

326

const articles = await Article.findAll({

327

where: {

328

searchVector: {

329

[Op.match]: sequelize.fn('plainto_tsquery', 'javascript programming')

330

}

331

}

332

});

333

334

// VALUES clause

335

const users = await User.findAll({

336

where: {

337

id: { [Op.in]: { [Op.values]: [[1], [2], [3]] } }

338

}

339

});

340

```

341

342

### Raw SQL Utilities

343

344

Utilities for building custom SQL expressions.

345

346

```typescript { .api }

347

/**

348

* Create SQL function call

349

* @param fn - Function name

350

* @param args - Function arguments

351

* @returns Fn instance

352

*/

353

fn(fn: string, ...args: any[]): Fn;

354

355

/**

356

* Reference table column

357

* @param col - Column name (can include table prefix)

358

* @returns Col instance

359

*/

360

col(col: string): Col;

361

362

/**

363

* Create raw SQL literal

364

* @param val - Raw SQL string

365

* @returns Literal instance

366

*/

367

literal(val: string): Literal;

368

369

/**

370

* Type casting

371

* @param val - Value to cast

372

* @param type - Target type

373

* @returns Cast instance

374

*/

375

cast(val: any, type: string): Cast;

376

377

/**

378

* WHERE condition builder

379

* @param attr - Attribute or expression

380

* @param comparator - Comparison operator

381

* @param logic - Value to compare against

382

* @returns Where instance

383

*/

384

where(attr: any, comparator: any, logic?: any): Where;

385

386

/**

387

* JSON path operations

388

* @param conditionsOrPath - JSON path or conditions

389

* @param value - Value to compare (if path provided)

390

* @returns JSON query condition

391

*/

392

json(conditionsOrPath: string | object, value?: any): object;

393

```

394

395

**Usage Examples:**

396

397

```typescript

398

import { fn, col, literal, cast, where, json } from "sequelize";

399

400

// SQL functions

401

const users = await User.findAll({

402

where: {

403

age: { [Op.gt]: fn('AVG', col('age')) }

404

}

405

});

406

407

// Column references

408

const users = await User.findAll({

409

where: where(col('user.created_at'), Op.gt, col('user.updated_at'))

410

});

411

412

// Raw SQL literals

413

const users = await User.findAll({

414

where: {

415

balance: { [Op.gt]: literal('(SELECT AVG(balance) FROM users)') }

416

}

417

});

418

419

// Type casting

420

const users = await User.findAll({

421

where: {

422

score: { [Op.gt]: cast('85.5', 'INTEGER') }

423

}

424

});

425

426

// JSON operations

427

const users = await User.findAll({

428

where: {

429

preferences: json('theme', 'dark'),

430

metadata: json({ 'user.settings.notifications': true })

431

}

432

});

433

434

// Complex example combining utilities

435

const users = await User.findAll({

436

where: where(

437

fn('DATE', col('created_at')),

438

Op.eq,

439

literal('CURRENT_DATE')

440

),

441

attributes: [

442

'id',

443

'firstName',

444

[fn('COUNT', col('posts.id')), 'postCount'],

445

[cast(col('age'), 'TEXT'), 'ageString']

446

],

447

include: [{

448

model: Post,

449

attributes: []

450

}],

451

group: ['user.id']

452

});

453

```

454

455

### Raw Query Execution

456

457

Execute raw SQL queries directly.

458

459

```typescript { .api }

460

/**

461

* Execute raw SQL query

462

* @param sql - SQL query string

463

* @param options - Query execution options

464

* @returns Promise resolving to query results

465

*/

466

query(sql: string, options?: QueryOptions): Promise<any>;

467

468

interface QueryOptions {

469

/** Bind parameters (named placeholders) */

470

bind?: { [key: string]: any };

471

/** Replacement parameters (positional placeholders) */

472

replacements?: { [key: string]: any } | any[];

473

/** Query type */

474

type?: QueryTypes;

475

/** Model to map results to */

476

model?: typeof Model;

477

/** Map results to model instances */

478

mapToModel?: boolean;

479

/** Return raw results */

480

raw?: boolean;

481

/** Nest results */

482

nest?: boolean;

483

/** Plain objects instead of instances */

484

plain?: boolean;

485

/** Transaction */

486

transaction?: Transaction;

487

/** Query logging */

488

logging?: boolean | ((sql: string, timing?: number) => void);

489

}

490

```

491

492

**Usage Examples:**

493

494

```typescript

495

// Basic raw query

496

const results = await sequelize.query(

497

'SELECT * FROM users WHERE age > 25',

498

{ type: QueryTypes.SELECT }

499

);

500

501

// With replacements

502

const results = await sequelize.query(

503

'SELECT * FROM users WHERE age > :age AND city = :city',

504

{

505

replacements: { age: 25, city: 'New York' },

506

type: QueryTypes.SELECT

507

}

508

);

509

510

// With bind parameters (safer for repeated queries)

511

const results = await sequelize.query(

512

'SELECT * FROM users WHERE age > $1 AND city = $2',

513

{

514

bind: [25, 'New York'],

515

type: QueryTypes.SELECT

516

}

517

);

518

519

// Map to model instances

520

const users = await sequelize.query(

521

'SELECT * FROM users WHERE active = true',

522

{

523

model: User,

524

mapToModel: true

525

}

526

);

527

528

// Insert/Update/Delete operations

529

await sequelize.query(

530

'UPDATE users SET last_login = NOW() WHERE id = :userId',

531

{

532

replacements: { userId: 123 },

533

type: QueryTypes.UPDATE

534

}

535

);

536

```