or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aggregation.mdconnection.mddocument.mderrors.mdindex.mdmodel.mdquery.mdschema.mdutilities.md

query.mddocs/

0

# Query Building

1

2

Fluent query builder with method chaining, population, lean queries, and advanced MongoDB query operations for flexible data retrieval.

3

4

## Capabilities

5

6

### Query Construction

7

8

Create and build queries with fluent method chaining and MongoDB operators.

9

10

```javascript { .api }

11

interface Query<ResultType, DocType> {

12

/**

13

* Add where conditions to query

14

* @param path - Field path or condition object

15

* @param val - Value for equality match

16

* @returns this query

17

*/

18

where(path: string | object, val?: any): this;

19

20

/**

21

* Specify equality condition

22

* @param value - Value to match

23

* @returns this query

24

*/

25

equals(value: any): this;

26

27

/**

28

* Greater than condition

29

* @param value - Comparison value

30

* @returns this query

31

*/

32

gt(value: any): this;

33

34

/**

35

* Greater than or equal condition

36

* @param value - Comparison value

37

* @returns this query

38

*/

39

gte(value: any): this;

40

41

/**

42

* Less than condition

43

* @param value - Comparison value

44

* @returns this query

45

*/

46

lt(value: any): this;

47

48

/**

49

* Less than or equal condition

50

* @param value - Comparison value

51

* @returns this query

52

*/

53

lte(value: any): this;

54

55

/**

56

* In array condition

57

* @param value - Array of values to match

58

* @returns this query

59

*/

60

in(value: any[]): this;

61

62

/**

63

* Not in array condition

64

* @param value - Array of values to exclude

65

* @returns this query

66

*/

67

nin(value: any[]): this;

68

69

/**

70

* Field exists condition

71

* @param val - True to check existence, false for non-existence

72

* @returns this query

73

*/

74

exists(val?: boolean): this;

75

76

/**

77

* Regular expression match

78

* @param val - Regular expression or string pattern

79

* @returns this query

80

*/

81

regex(val: RegExp | string): this;

82

83

/**

84

* Array size condition

85

* @param val - Required array length

86

* @returns this query

87

*/

88

size(val: number): this;

89

90

/**

91

* All array elements match

92

* @param val - Array of values that must all be present

93

* @returns this query

94

*/

95

all(val: any[]): this;

96

97

/**

98

* Element match condition for arrays

99

* @param val - Condition object for array elements

100

* @returns this query

101

*/

102

elemMatch(val: any): this;

103

104

/**

105

* Logical OR conditions

106

* @param conditions - Array of condition objects

107

* @returns this query

108

*/

109

or(conditions: any[]): this;

110

111

/**

112

* Logical AND conditions

113

* @param conditions - Array of condition objects

114

* @returns this query

115

*/

116

and(conditions: any[]): this;

117

118

/**

119

* Logical NOR conditions

120

* @param conditions - Array of condition objects

121

* @returns this query

122

*/

123

nor(conditions: any[]): this;

124

125

/**

126

* Return lean objects instead of Mongoose documents

127

* @param val - Enable/disable lean mode

128

* @returns this query

129

*/

130

lean<T = any>(val?: boolean): Query<T>;

131

132

/**

133

* Set cursor batch size for streaming

134

* @param val - Batch size

135

* @returns this query

136

*/

137

batchSize(val: number): this;

138

139

/**

140

* Allow disk usage for large operations

141

* @param v - Allow disk usage

142

* @returns this query

143

*/

144

allowDiskUse(v: boolean): this;

145

146

/**

147

* Add comment to query for profiling

148

* @param val - Comment string

149

* @returns this query

150

*/

151

comment(val: string): this;

152

153

/**

154

* Return cursor for streaming results

155

* @param options - Cursor options

156

* @returns Query cursor

157

*/

158

cursor(options?: any): QueryCursor<DocType>;

159

160

/**

161

* Set query session for transactions

162

* @param session - MongoDB session

163

* @returns this query

164

*/

165

session(session: ClientSession): this;

166

167

/**

168

* Transform query results before returning

169

* @param fn - Transform function

170

* @returns this query

171

*/

172

transform(fn: Function): this;

173

174

/**

175

* Set maximum time for query execution

176

* @param ms - Maximum time in milliseconds

177

* @returns this query

178

*/

179

maxTimeMS(ms: number): this;

180

181

/**

182

* Get query options object

183

* @returns Current query options

184

*/

185

getOptions(): QueryOptions;

186

187

/**

188

* Check if query has projection

189

* @returns True if query has field selection

190

*/

191

selected(): boolean;

192

193

/**

194

* Promise then handler

195

* @param resolve - Success handler

196

* @param reject - Error handler

197

* @returns Promise

198

*/

199

then(resolve?: Function, reject?: Function): Promise<ResultType>;

200

201

/**

202

* Promise catch handler

203

* @param reject - Error handler

204

* @returns Promise

205

*/

206

catch(reject?: (reason: any) => any): Promise<ResultType>;

207

}

208

```

209

210

**Usage Examples:**

211

212

```javascript

213

const User = mongoose.model('User', userSchema);

214

215

// Basic conditions

216

const adults = await User.find().where('age').gte(18);

217

const youngAdults = await User.find().where('age').gte(18).lte(30);

218

219

// Multiple conditions

220

const activeUsers = await User.find()

221

.where('status').equals('active')

222

.where('lastLogin').gte(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000));

223

224

// Array conditions

225

const usersWithTags = await User.find()

226

.where('tags').in(['premium', 'verified'])

227

.where('skills').size(3)

228

.where('certifications').exists(true);

229

230

// Text search

231

const searchResults = await User.find()

232

.where('name').regex(/john/i)

233

.where('bio').regex('developer');

234

235

// Complex conditions

236

const complexQuery = await User.find()

237

.or([

238

{ age: { $lt: 25 } },

239

{ status: 'premium' }

240

])

241

.and([

242

{ active: true },

243

{ verified: true }

244

]);

245

```

246

247

### Field Selection and Projection

248

249

Control which fields are returned in query results.

250

251

```javascript { .api }

252

interface Query<ResultType, DocType> {

253

/**

254

* Select fields to include or exclude

255

* @param fields - Field selection string or object

256

* @returns this query

257

*/

258

select(fields: string | object): this;

259

260

/**

261

* Exclude specific fields

262

* @param fields - Fields to exclude

263

* @returns this query

264

*/

265

deselect(fields: string): this;

266

267

/**

268

* Return distinct values for a field

269

* @param field - Field to get distinct values for

270

* @returns Query for distinct values

271

*/

272

distinct(field: string): Query<any[], DocType>;

273

}

274

```

275

276

**Usage Examples:**

277

278

```javascript

279

// Select specific fields

280

const users = await User.find().select('name email age');

281

const users = await User.find().select({ name: 1, email: 1, age: 1 });

282

283

// Exclude fields

284

const users = await User.find().select('-password -secret');

285

const users = await User.find().select({ password: 0, secret: 0 });

286

287

// Mixed selection (include some, exclude others)

288

const users = await User.find().select('name email -_id');

289

290

// Get distinct values

291

const ages = await User.find().distinct('age');

292

const statuses = await User.find({ active: true }).distinct('status');

293

```

294

295

### Sorting and Pagination

296

297

Sort results and implement pagination with limit and skip.

298

299

```javascript { .api }

300

interface Query<ResultType, DocType> {

301

/**

302

* Sort query results

303

* @param sort - Sort specification

304

* @returns this query

305

*/

306

sort(sort: string | object): this;

307

308

/**

309

* Limit number of results

310

* @param val - Maximum number of documents to return

311

* @returns this query

312

*/

313

limit(val: number): this;

314

315

/**

316

* Skip number of results

317

* @param val - Number of documents to skip

318

* @returns this query

319

*/

320

skip(val: number): this;

321

322

/**

323

* Set query slice for arrays

324

* @param path - Array field path

325

* @param val - Number of elements or [skip, limit] array

326

* @returns this query

327

*/

328

slice(path: string, val: number | [number, number]): this;

329

}

330

```

331

332

**Usage Examples:**

333

334

```javascript

335

// Sort by single field

336

const users = await User.find().sort('name'); // Ascending

337

const users = await User.find().sort('-createdAt'); // Descending

338

339

// Sort by multiple fields

340

const users = await User.find().sort({ age: -1, name: 1 });

341

const users = await User.find().sort('age -name');

342

343

// Pagination

344

const page = 2;

345

const limit = 10;

346

const users = await User.find()

347

.sort('-createdAt')

348

.skip((page - 1) * limit)

349

.limit(limit);

350

351

// Array slicing

352

const posts = await Post.find()

353

.select('title comments')

354

.slice('comments', 5) // First 5 comments

355

.slice('tags', [2, 5]); // Skip 2, take 5 tags

356

```

357

358

### Population

359

360

Populate referenced documents with flexible options and nested population.

361

362

```javascript { .api }

363

interface Query<ResultType, DocType> {

364

/**

365

* Populate referenced fields

366

* @param path - Path to populate or populate options

367

* @returns this query

368

*/

369

populate(path: string | PopulateOptions | PopulateOptions[]): this;

370

371

/**

372

* Populate virtual fields

373

* @param path - Virtual path to populate

374

* @returns this query

375

*/

376

populateVirtuals(path: string): this;

377

}

378

379

interface PopulateOptions {

380

/** Path to populate */

381

path: string;

382

383

/** Fields to select from populated documents */

384

select?: string | object;

385

386

/** Model to populate from */

387

model?: string | Model<any>;

388

389

/** Additional query conditions for populated documents */

390

match?: any;

391

392

/** Sort populated documents */

393

sort?: any;

394

395

/** Limit populated documents */

396

limit?: number;

397

398

/** Skip populated documents */

399

skip?: number;

400

401

/** Populate nested fields */

402

populate?: PopulateOptions | PopulateOptions[];

403

404

/** Transform populated results */

405

transform?: Function;

406

407

/** Preserve null and undefined values */

408

strictPopulate?: boolean;

409

410

/** Count instead of populating documents */

411

count?: boolean;

412

}

413

```

414

415

**Usage Examples:**

416

417

```javascript

418

// Basic population

419

const posts = await Post.find().populate('author');

420

421

// Population with field selection

422

const posts = await Post.find().populate('author', 'name email');

423

424

// Population with conditions

425

const posts = await Post.find().populate({

426

path: 'comments',

427

match: { approved: true },

428

select: 'text author createdAt',

429

sort: { createdAt: -1 },

430

limit: 10

431

});

432

433

// Multiple populations

434

const posts = await Post.find().populate([

435

{ path: 'author', select: 'name' },

436

{ path: 'category', select: 'name slug' },

437

{

438

path: 'comments',

439

populate: { path: 'author', select: 'name avatar' }

440

}

441

]);

442

443

// Nested population

444

const users = await User.find().populate({

445

path: 'posts',

446

populate: {

447

path: 'comments',

448

populate: {

449

path: 'author',

450

select: 'name'

451

}

452

}

453

});

454

455

// Virtual population

456

userSchema.virtual('posts', {

457

ref: 'Post',

458

localField: '_id',

459

foreignField: 'author'

460

});

461

462

const users = await User.find().populate('posts');

463

```

464

465

### Query Execution

466

467

Execute queries and control result format and behavior.

468

469

```javascript { .api }

470

interface Query<ResultType, DocType> {

471

/**

472

* Execute the query

473

* @returns Promise resolving to query results

474

*/

475

exec(): Promise<ResultType>;

476

477

/**

478

* Execute query and return a cursor

479

* @param options - Cursor options

480

* @returns Query cursor for streaming results

481

*/

482

cursor(options?: CursorOptions): QueryCursor<DocType>;

483

484

/**

485

* Execute query and return readable stream

486

* @param options - Stream options

487

* @returns Readable stream of documents

488

*/

489

stream(options?: any): NodeJS.ReadableStream;

490

491

/**

492

* Get query execution plan

493

* @param verbosity - Explanation verbosity level

494

* @returns Promise resolving to execution plan

495

*/

496

explain(verbosity?: string): Promise<any>;

497

498

/**

499

* Return lean documents (plain objects)

500

* @param val - Enable/disable lean mode

501

* @returns this query

502

*/

503

lean(val?: boolean | object): this;

504

505

/**

506

* Set read preference

507

* @param pref - Read preference

508

* @param tags - Read preference tags

509

* @returns this query

510

*/

511

read(pref: string, tags?: any[]): this;

512

513

/**

514

* Set query comment for profiling

515

* @param val - Comment string

516

* @returns this query

517

*/

518

comment(val: string): this;

519

520

/**

521

* Force index usage

522

* @param val - Index specification

523

* @returns this query

524

*/

525

hint(val: object): this;

526

527

/**

528

* Set maximum execution time

529

* @param ms - Maximum time in milliseconds

530

* @returns this query

531

*/

532

maxTimeMS(ms: number): this;

533

}

534

535

interface CursorOptions {

536

/** Transform function for each document */

537

transform?: Function;

538

539

/** Batch size for cursor */

540

batchSize?: number;

541

542

/** Use lean mode */

543

lean?: boolean;

544

}

545

```

546

547

**Usage Examples:**

548

549

```javascript

550

// Basic execution

551

const users = await User.find({ active: true }).exec();

552

553

// Lean queries (return plain objects)

554

const users = await User.find().lean();

555

const fastUsers = await User.find().lean({ virtuals: true });

556

557

// Cursor for large datasets

558

const cursor = User.find().cursor();

559

for (let doc = await cursor.next(); doc != null; doc = await cursor.next()) {

560

console.log(doc.name);

561

}

562

563

// Streaming

564

const stream = User.find().stream();

565

stream.on('data', (doc) => {

566

console.log('Received:', doc.name);

567

});

568

569

// Query optimization

570

const users = await User.find()

571

.hint({ email: 1 }) // Force index usage

572

.maxTimeMS(5000) // 5 second timeout

573

.comment('User lookup query')

574

.read('secondary'); // Read from secondary

575

576

// Execution plan

577

const plan = await User.find({ age: { $gte: 18 } }).explain('executionStats');

578

console.log('Query execution plan:', plan);

579

```

580

581

### Advanced Query Options

582

583

Configure query behavior, collation, and database-specific options.

584

585

```javascript { .api }

586

interface Query<ResultType, DocType> {

587

/**

588

* Use database session for transactions

589

* @param session - MongoDB session

590

* @returns this query

591

*/

592

session(session: ClientSession): this;

593

594

/**

595

* Set collation for string comparisons

596

* @param collation - Collation specification

597

* @returns this query

598

*/

599

collation(collation: CollationOptions): this;

600

601

/**

602

* Set batch size for cursor operations

603

* @param val - Batch size

604

* @returns this query

605

*/

606

batchSize(val: number): this;

607

608

/**

609

* Allow disk usage for large operations

610

* @param val - Enable disk usage

611

* @returns this query

612

*/

613

allowDiskUse(val: boolean): this;

614

615

/**

616

* Set maximum number of documents to scan

617

* @param val - Maximum scan count

618

* @returns this query

619

*/

620

maxscan(val: number): this;

621

622

/**

623

* Enable/disable query timeout

624

* @param val - Enable timeout

625

* @returns this query

626

*/

627

timeout(val: boolean): this;

628

629

/**

630

* Cast query conditions using schema

631

* @param model - Model to use for casting

632

* @param obj - Object to cast (optional)

633

* @returns Casted conditions

634

*/

635

cast(model?: Model<DocType>, obj?: any): any;

636

}

637

638

interface CollationOptions {

639

locale: string;

640

caseLevel?: boolean;

641

caseFirst?: string;

642

strength?: number;

643

numericOrdering?: boolean;

644

alternate?: string;

645

maxVariable?: string;

646

backwards?: boolean;

647

}

648

```

649

650

**Usage Examples:**

651

652

```javascript

653

// Transaction session

654

const session = await mongoose.startSession();

655

session.startTransaction();

656

657

try {

658

const users = await User.find({ status: 'pending' })

659

.session(session);

660

661

await User.updateMany(

662

{ _id: { $in: users.map(u => u._id) } },

663

{ status: 'approved' }

664

).session(session);

665

666

await session.commitTransaction();

667

} catch (error) {

668

await session.abortTransaction();

669

throw error;

670

} finally {

671

session.endSession();

672

}

673

674

// Collation for case-insensitive sorting

675

const users = await User.find()

676

.sort({ name: 1 })

677

.collation({ locale: 'en', strength: 2 });

678

679

// Performance tuning

680

const results = await User.find({ status: 'active' })

681

.batchSize(100)

682

.maxTimeMS(10000)

683

.allowDiskUse(true)

684

.maxscan(1000);

685

```

686

687

## Types

688

689

```javascript { .api }

690

interface QueryCursor<T> extends NodeJS.ReadableStream {

691

/** Get next document from cursor */

692

next(): Promise<T | null>;

693

694

/** Close the cursor */

695

close(): Promise<void>;

696

697

/** Check if cursor is closed */

698

closed: boolean;

699

700

/** Transform each document */

701

map<U>(fn: (doc: T) => U): QueryCursor<U>;

702

703

/** Add cursor event listeners */

704

on(event: 'data' | 'error' | 'end', listener: Function): this;

705

}

706

707

type ProjectionType<T> =

708

| string

709

| { [K in keyof T]?: 1 | 0 | boolean }

710

| { [key: string]: 1 | 0 | boolean };

711

712

interface QueryOptions {

713

/** Use lean mode */

714

lean?: boolean;

715

716

/** Population options */

717

populate?: string | PopulateOptions | PopulateOptions[];

718

719

/** Field selection */

720

select?: string | object;

721

722

/** Sort specification */

723

sort?: string | object;

724

725

/** Limit results */

726

limit?: number;

727

728

/** Skip results */

729

skip?: number;

730

731

/** Maximum time for query execution */

732

maxTimeMS?: number;

733

734

/** Query comment */

735

comment?: string;

736

737

/** Force index usage */

738

hint?: object;

739

740

/** Read preference */

741

read?: any;

742

743

/** Database session */

744

session?: ClientSession;

745

746

/** Collation options */

747

collation?: CollationOptions;

748

749

/** Batch size */

750

batchSize?: number;

751

752

/** Allow disk usage */

753

allowDiskUse?: boolean;

754

}

755

```