0
# Query System
1
2
Advanced querying capabilities with MongoDB-compatible operators for complex data retrieval, filtering, and update operations.
3
4
## Capabilities
5
6
### Comparison Operators
7
8
Standard comparison operators for numeric, string, and date comparisons.
9
10
```javascript { .api }
11
/**
12
* Comparison query operators
13
*/
14
interface ComparisonOperators {
15
$lt: any; // Less than
16
$lte: any; // Less than or equal to
17
$gt: any; // Greater than
18
$gte: any; // Greater than or equal to
19
$ne: any; // Not equal to
20
$in: any[]; // Value exists in array
21
$nin: any[]; // Value does not exist in array
22
}
23
```
24
25
**Usage Examples:**
26
27
```javascript
28
const db = new Datastore({ filename: './products.db', autoload: true });
29
30
// Numeric comparisons
31
db.find({ price: { $lt: 100 } }, (err, cheapProducts) => {
32
console.log('Products under $100:', cheapProducts);
33
});
34
35
db.find({ stock: { $gte: 10, $lte: 50 } }, (err, limitedStock) => {
36
console.log('Products with limited stock:', limitedStock);
37
});
38
39
// String comparisons (lexicographic)
40
db.find({ category: { $ne: 'electronics' } }, (err, nonElectronics) => {
41
console.log('Non-electronics products:', nonElectronics);
42
});
43
44
// Array membership
45
db.find({ category: { $in: ['books', 'music', 'movies'] } }, (err, media) => {
46
console.log('Media products:', media);
47
});
48
49
db.find({ status: { $nin: ['discontinued', 'out-of-stock'] } }, (err, available) => {
50
console.log('Available products:', available);
51
});
52
53
// Date comparisons
54
const lastMonth = new Date();
55
lastMonth.setMonth(lastMonth.getMonth() - 1);
56
57
db.find({ createdAt: { $gte: lastMonth } }, (err, recentProducts) => {
58
console.log('Products added in the last month:', recentProducts);
59
});
60
```
61
62
### String and Pattern Operators
63
64
Pattern matching and string-specific query operations.
65
66
```javascript { .api }
67
/**
68
* String and pattern operators
69
*/
70
interface PatternOperators {
71
$regex: RegExp | string; // Regular expression match
72
$exists: boolean; // Field existence check
73
}
74
```
75
76
**Usage Examples:**
77
78
```javascript
79
const db = new Datastore({ filename: './users.db', autoload: true });
80
81
// Regular expression matching
82
db.find({ email: { $regex: /@gmail\.com$/ } }, (err, gmailUsers) => {
83
console.log('Gmail users:', gmailUsers);
84
});
85
86
// Case-insensitive regex with string
87
db.find({ name: { $regex: /^john/i } }, (err, johns) => {
88
console.log('Users named John (case insensitive):', johns);
89
});
90
91
// Field existence checks
92
db.find({ phoneNumber: { $exists: true } }, (err, usersWithPhone) => {
93
console.log('Users with phone numbers:', usersWithPhone);
94
});
95
96
db.find({ deletedAt: { $exists: false } }, (err, activeUsers) => {
97
console.log('Active users (not deleted):', activeUsers);
98
});
99
100
// Combining regex with other operators
101
db.find({
102
$and: [
103
{ email: { $regex: /@company\.com$/ } },
104
{ status: { $ne: 'inactive' } }
105
]
106
}, (err, activeEmployees) => {
107
console.log('Active company employees:', activeEmployees);
108
});
109
```
110
111
### Array Operators
112
113
Specialized operators for querying array fields and their contents.
114
115
```javascript { .api }
116
/**
117
* Array-specific operators
118
*/
119
interface ArrayOperators {
120
$size: number; // Array size equals specified number
121
$elemMatch: object; // At least one array element matches all criteria
122
}
123
```
124
125
**Usage Examples:**
126
127
```javascript
128
const db = new Datastore({ filename: './orders.db', autoload: true });
129
130
// Array size matching
131
db.find({ items: { $size: 3 } }, (err, ordersWithThreeItems) => {
132
console.log('Orders with exactly 3 items:', ordersWithThreeItems);
133
});
134
135
// Element matching in arrays
136
db.find({
137
items: {
138
$elemMatch: {
139
category: 'electronics',
140
price: { $gt: 500 }
141
}
142
}
143
}, (err, expensiveElectronicsOrders) => {
144
console.log('Orders with expensive electronics:', expensiveElectronicsOrders);
145
});
146
147
// Array field value matching (direct)
148
db.find({ tags: 'urgent' }, (err, urgentOrders) => {
149
// Matches documents where tags array contains 'urgent'
150
console.log('Urgent orders:', urgentOrders);
151
});
152
153
// Multiple array conditions
154
db.find({
155
$and: [
156
{ tags: { $size: { $gte: 2 } } },
157
{ tags: 'priority' }
158
]
159
}, (err, priorityOrders) => {
160
console.log('Priority orders with multiple tags:', priorityOrders);
161
});
162
```
163
164
### Logical Operators
165
166
Boolean logic for combining multiple query conditions.
167
168
```javascript { .api }
169
/**
170
* Logical operators for combining conditions
171
*/
172
interface LogicalOperators {
173
$or: object[]; // Logical OR - at least one condition must match
174
$and: object[]; // Logical AND - all conditions must match
175
$not: object; // Logical NOT - condition must not match
176
$where: function; // Custom function evaluation
177
}
178
```
179
180
**Usage Examples:**
181
182
```javascript
183
const db = new Datastore({ filename: './products.db', autoload: true });
184
185
// OR conditions
186
db.find({
187
$or: [
188
{ category: 'electronics' },
189
{ price: { $lt: 50 } },
190
{ featured: true }
191
]
192
}, (err, products) => {
193
console.log('Electronics OR cheap OR featured products:', products);
194
});
195
196
// AND conditions (explicit)
197
db.find({
198
$and: [
199
{ price: { $gte: 100 } },
200
{ stock: { $gt: 0 } },
201
{ rating: { $gte: 4.0 } }
202
]
203
}, (err, premiumProducts) => {
204
console.log('Premium available products:', premiumProducts);
205
});
206
207
// NOT conditions
208
db.find({
209
$not: {
210
category: { $in: ['discontinued', 'clearance'] }
211
}
212
}, (err, regularProducts) => {
213
console.log('Regular products (not discontinued/clearance):', regularProducts);
214
});
215
216
// Custom function evaluation
217
db.find({
218
$where: function() {
219
return this.price > this.originalPrice * 0.5;
220
}
221
}, (err, significantlyDiscounted) => {
222
console.log('Products with >50% discount:', significantlyDiscounted);
223
});
224
225
// Complex nested logic
226
db.find({
227
$and: [
228
{
229
$or: [
230
{ category: 'books' },
231
{ category: 'ebooks' }
232
]
233
},
234
{
235
$not: {
236
status: 'out-of-print'
237
}
238
},
239
{ price: { $lte: 30 } }
240
]
241
}, (err, affordableBooks) => {
242
console.log('Affordable available books:', affordableBooks);
243
});
244
```
245
246
### Update Operators
247
248
Operators for modifying documents without replacing them entirely.
249
250
```javascript { .api }
251
/**
252
* Update operators for document modification
253
*/
254
interface UpdateOperators {
255
$set: object; // Set field values
256
$unset: object; // Remove fields
257
$inc: object; // Increment numeric fields
258
$push: object; // Add elements to arrays
259
$addToSet: object; // Add unique elements to arrays
260
$pop: object; // Remove first/last array elements
261
$pull: object; // Remove matching array elements
262
$min: object; // Set to minimum value
263
$max: object; // Set to maximum value
264
}
265
266
/**
267
* Array update modifiers
268
*/
269
interface ArrayUpdateModifiers {
270
$each: any[]; // Apply operation to each element (used with $push, $addToSet)
271
$slice: number; // Limit array size after $push operation
272
}
273
```
274
275
**Usage Examples:**
276
277
```javascript
278
const db = new Datastore({ filename: './users.db', autoload: true });
279
280
// Set field values
281
db.update(
282
{ name: 'Alice' },
283
{ $set: { status: 'premium', lastLogin: new Date() } },
284
{},
285
(err, numUpdated) => {
286
console.log('Set status and lastLogin for Alice');
287
}
288
);
289
290
// Remove fields
291
db.update(
292
{ status: 'deleted' },
293
{ $unset: { email: true, phoneNumber: true } },
294
{ multi: true },
295
(err, numUpdated) => {
296
console.log('Removed personal info from deleted accounts');
297
}
298
);
299
300
// Increment numeric values
301
db.update(
302
{ name: 'Bob' },
303
{ $inc: { loginCount: 1, points: 10 } },
304
{},
305
(err, numUpdated) => {
306
console.log('Incremented login count and points for Bob');
307
}
308
);
309
310
// Array operations - push single element
311
db.update(
312
{ name: 'Charlie' },
313
{ $push: { tags: 'vip' } },
314
{},
315
(err, numUpdated) => {
316
console.log('Added VIP tag to Charlie');
317
}
318
);
319
320
// Array operations - push multiple elements with slice
321
db.update(
322
{ name: 'Diana' },
323
{
324
$push: {
325
recentActivity: {
326
$each: ['login', 'purchase', 'review'],
327
$slice: -5 // Keep only last 5 activities
328
}
329
}
330
},
331
{},
332
(err, numUpdated) => {
333
console.log('Added recent activities to Diana (keeping last 5)');
334
}
335
);
336
337
// Add to set (unique elements only)
338
db.update(
339
{ name: 'Eve' },
340
{ $addToSet: { skills: { $each: ['javascript', 'python', 'javascript'] } } },
341
{},
342
(err, numUpdated) => {
343
console.log('Added unique skills to Eve');
344
}
345
);
346
347
// Remove array elements
348
db.update(
349
{ name: 'Frank' },
350
{ $pull: { tags: 'temporary' } },
351
{},
352
(err, numUpdated) => {
353
console.log('Removed temporary tags from Frank');
354
}
355
);
356
357
// Pop elements from array
358
db.update(
359
{ name: 'Grace' },
360
{ $pop: { notifications: 1 } }, // 1 for last, -1 for first
361
{},
362
(err, numUpdated) => {
363
console.log('Removed last notification from Grace');
364
}
365
);
366
367
// Min/Max operations
368
db.update(
369
{ name: 'Henry' },
370
{
371
$min: { lowestScore: 85 }, // Set only if current value is higher
372
$max: { highestScore: 92 } // Set only if current value is lower
373
},
374
{},
375
(err, numUpdated) => {
376
console.log('Updated min/max scores for Henry');
377
}
378
);
379
```
380
381
### Nested Field Queries
382
383
Query and update nested object fields using dot notation.
384
385
```javascript { .api }
386
/**
387
* Dot notation for nested field access
388
* Use string keys with dots to access nested properties
389
*/
390
interface DotNotation {
391
'field.subfield': any; // Access nested object properties
392
'arrayField.0.property': any; // Access array element properties
393
'deep.nested.field': any; // Access deeply nested properties
394
}
395
```
396
397
**Usage Examples:**
398
399
```javascript
400
const db = new Datastore({ filename: './profiles.db', autoload: true });
401
402
// Sample document structure:
403
// {
404
// name: 'John',
405
// address: {
406
// street: '123 Main St',
407
// city: 'Boston',
408
// coordinates: { lat: 42.3601, lng: -71.0589 }
409
// },
410
// orders: [
411
// { id: 1, amount: 100, status: 'completed' },
412
// { id: 2, amount: 250, status: 'pending' }
413
// ]
414
// }
415
416
// Query nested object fields
417
db.find({ 'address.city': 'Boston' }, (err, bostonUsers) => {
418
console.log('Users in Boston:', bostonUsers);
419
});
420
421
db.find({ 'address.coordinates.lat': { $gte: 40 } }, (err, northernUsers) => {
422
console.log('Users in northern locations:', northernUsers);
423
});
424
425
// Query array elements
426
db.find({ 'orders.status': 'pending' }, (err, usersWithPending) => {
427
console.log('Users with pending orders:', usersWithPending);
428
});
429
430
// Update nested fields
431
db.update(
432
{ name: 'John' },
433
{ $set: { 'address.street': '456 Oak Ave' } },
434
{},
435
(err, numUpdated) => {
436
console.log('Updated Johns street address');
437
}
438
);
439
440
// Update nested arrays
441
db.update(
442
{ 'orders.id': 2 },
443
{ $set: { 'orders.$.status': 'shipped' } },
444
{},
445
(err, numUpdated) => {
446
console.log('Updated order status');
447
}
448
);
449
```
450
451
## Query Performance Tips
452
453
- Create indexes on frequently queried fields using `ensureIndex()`
454
- Use specific field values instead of complex operators when possible
455
- Combine multiple conditions in a single query rather than chaining queries
456
- Use projections to limit returned field data
457
- Consider using `findOne()` when you only need a single result
458
- Use `$exists: false` instead of `$ne: null` for better performance on missing fields