chub-dev 0.1.0 → 0.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,2041 @@
1
+ ---
2
+ name: atlas
3
+ description: "MongoDB Node.js driver for interacting with MongoDB Atlas databases using the official JavaScript/TypeScript SDK."
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "6.20.0"
7
+ updated-on: "2026-03-01"
8
+ source: maintainer
9
+ tags: "mongodb,atlas,database,nosql,driver"
10
+ ---
11
+
12
+ # MongoDB Atlas Coding Guidelines (JavaScript/TypeScript)
13
+
14
+ You are a MongoDB Atlas coding expert. Help me with writing code using the MongoDB Node.js driver calling the official libraries and SDKs.
15
+
16
+ ## Golden Rule: Use the Correct and Current SDK
17
+
18
+ Always use the official MongoDB Node.js driver for all MongoDB Atlas interactions.
19
+
20
+ - **Library Name:** MongoDB Node.js Driver
21
+ - **NPM Package:** `mongodb`
22
+ - **GitHub:** https://github.com/mongodb/node-mongodb-native
23
+
24
+ **Installation:**
25
+
26
+ ```bash
27
+ npm install mongodb
28
+ ```
29
+
30
+ **Import Patterns:**
31
+
32
+ ```javascript
33
+ // ES6 import (recommended)
34
+ import { MongoClient } from 'mongodb';
35
+
36
+ // CommonJS require
37
+ const { MongoClient } = require('mongodb');
38
+
39
+ // Additional utilities
40
+ import { MongoClient, ObjectId, Timestamp } from 'mongodb';
41
+ ```
42
+
43
+ **Do NOT use:**
44
+ - Deprecated MongoDB packages
45
+ - Third-party MongoDB wrappers (unless specifically requested)
46
+ - Old connection patterns from MongoDB driver v2 or v3
47
+
48
+ ## Installation and Environment Setup
49
+
50
+ ```bash
51
+ npm install mongodb
52
+ ```
53
+
54
+ **Environment Variables Setup:**
55
+
56
+ Create a `.env` file in your project root:
57
+
58
+ ```bash
59
+ MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/database?retryWrites=true&w=majority
60
+ ```
61
+
62
+ **Using dotenv for environment variables:**
63
+
64
+ ```bash
65
+ npm install dotenv
66
+ ```
67
+
68
+ ```javascript
69
+ import 'dotenv/config';
70
+ import { MongoClient } from 'mongodb';
71
+
72
+ const uri = process.env.MONGODB_URI;
73
+ ```
74
+
75
+ ## Initialization and Connection
76
+
77
+ The MongoDB driver requires creating a `MongoClient` instance for all database operations.
78
+
79
+ **Basic Connection:**
80
+
81
+ ```javascript
82
+ import { MongoClient } from 'mongodb';
83
+
84
+ const uri = process.env.MONGODB_URI;
85
+ const client = new MongoClient(uri);
86
+
87
+ async function main() {
88
+ try {
89
+ await client.connect();
90
+ console.log('Connected to MongoDB Atlas');
91
+
92
+ const database = client.db('myDatabase');
93
+ const collection = database.collection('myCollection');
94
+
95
+ // Perform operations...
96
+
97
+ } finally {
98
+ await client.close();
99
+ }
100
+ }
101
+
102
+ main().catch(console.error);
103
+ ```
104
+
105
+ **Connection with Options:**
106
+
107
+ ```javascript
108
+ import { MongoClient, ServerApiVersion } from 'mongodb';
109
+
110
+ const uri = process.env.MONGODB_URI;
111
+
112
+ const client = new MongoClient(uri, {
113
+ serverApi: {
114
+ version: ServerApiVersion.v1,
115
+ strict: true,
116
+ deprecationErrors: true,
117
+ }
118
+ });
119
+
120
+ async function run() {
121
+ try {
122
+ await client.connect();
123
+ await client.db('admin').command({ ping: 1 });
124
+ console.log('Pinged your deployment. Successfully connected to MongoDB!');
125
+ } finally {
126
+ await client.close();
127
+ }
128
+ }
129
+
130
+ run().catch(console.error);
131
+ ```
132
+
133
+ **Reusable Connection Pattern:**
134
+
135
+ ```javascript
136
+ import { MongoClient } from 'mongodb';
137
+
138
+ let client;
139
+ let clientPromise;
140
+
141
+ const uri = process.env.MONGODB_URI;
142
+ const options = {};
143
+
144
+ if (process.env.NODE_ENV === 'development') {
145
+ // In development mode, use a global variable to preserve connection
146
+ if (!global._mongoClientPromise) {
147
+ client = new MongoClient(uri, options);
148
+ global._mongoClientPromise = client.connect();
149
+ }
150
+ clientPromise = global._mongoClientPromise;
151
+ } else {
152
+ // In production mode, create a new client
153
+ client = new MongoClient(uri, options);
154
+ clientPromise = client.connect();
155
+ }
156
+
157
+ export default clientPromise;
158
+ ```
159
+
160
+ ## CRUD Operations
161
+
162
+ ### Insert Documents
163
+
164
+ **Insert One Document:**
165
+
166
+ ```javascript
167
+ import { MongoClient } from 'mongodb';
168
+
169
+ const client = new MongoClient(process.env.MONGODB_URI);
170
+
171
+ async function insertDocument() {
172
+ try {
173
+ await client.connect();
174
+ const database = client.db('sample_db');
175
+ const collection = database.collection('users');
176
+
177
+ const doc = {
178
+ name: 'John Doe',
179
+ email: 'john@example.com',
180
+ age: 30,
181
+ createdAt: new Date()
182
+ };
183
+
184
+ const result = await collection.insertOne(doc);
185
+ console.log(`Document inserted with _id: ${result.insertedId}`);
186
+
187
+ } finally {
188
+ await client.close();
189
+ }
190
+ }
191
+
192
+ insertDocument().catch(console.error);
193
+ ```
194
+
195
+ **Insert Multiple Documents:**
196
+
197
+ ```javascript
198
+ async function insertMultipleDocuments() {
199
+ try {
200
+ await client.connect();
201
+ const database = client.db('sample_db');
202
+ const collection = database.collection('users');
203
+
204
+ const docs = [
205
+ { name: 'Alice', email: 'alice@example.com', age: 25 },
206
+ { name: 'Bob', email: 'bob@example.com', age: 32 },
207
+ { name: 'Charlie', email: 'charlie@example.com', age: 28 }
208
+ ];
209
+
210
+ const result = await collection.insertMany(docs);
211
+ console.log(`${result.insertedCount} documents inserted`);
212
+ console.log('Inserted IDs:', result.insertedIds);
213
+
214
+ } finally {
215
+ await client.close();
216
+ }
217
+ }
218
+
219
+ insertMultipleDocuments().catch(console.error);
220
+ ```
221
+
222
+ **Insert with Options:**
223
+
224
+ ```javascript
225
+ async function insertWithOptions() {
226
+ try {
227
+ await client.connect();
228
+ const database = client.db('sample_db');
229
+ const collection = database.collection('users');
230
+
231
+ const doc = { name: 'David', email: 'david@example.com' };
232
+
233
+ const result = await collection.insertOne(doc, {
234
+ writeConcern: { w: 'majority', wtimeout: 5000 }
235
+ });
236
+
237
+ console.log(`Document inserted: ${result.insertedId}`);
238
+
239
+ } finally {
240
+ await client.close();
241
+ }
242
+ }
243
+
244
+ insertWithOptions().catch(console.error);
245
+ ```
246
+
247
+ ### Find Documents
248
+
249
+ **Find All Documents:**
250
+
251
+ ```javascript
252
+ async function findAllDocuments() {
253
+ try {
254
+ await client.connect();
255
+ const database = client.db('sample_db');
256
+ const collection = database.collection('users');
257
+
258
+ const cursor = collection.find({});
259
+ const documents = await cursor.toArray();
260
+
261
+ console.log('All documents:', documents);
262
+
263
+ } finally {
264
+ await client.close();
265
+ }
266
+ }
267
+
268
+ findAllDocuments().catch(console.error);
269
+ ```
270
+
271
+ **Find with Filter:**
272
+
273
+ ```javascript
274
+ async function findWithFilter() {
275
+ try {
276
+ await client.connect();
277
+ const database = client.db('sample_db');
278
+ const collection = database.collection('users');
279
+
280
+ // Find users older than 25
281
+ const query = { age: { $gt: 25 } };
282
+ const cursor = collection.find(query);
283
+ const results = await cursor.toArray();
284
+
285
+ console.log('Users older than 25:', results);
286
+
287
+ } finally {
288
+ await client.close();
289
+ }
290
+ }
291
+
292
+ findWithFilter().catch(console.error);
293
+ ```
294
+
295
+ **Find One Document:**
296
+
297
+ ```javascript
298
+ async function findOneDocument() {
299
+ try {
300
+ await client.connect();
301
+ const database = client.db('sample_db');
302
+ const collection = database.collection('users');
303
+
304
+ const query = { email: 'john@example.com' };
305
+ const user = await collection.findOne(query);
306
+
307
+ if (user) {
308
+ console.log('Found user:', user);
309
+ } else {
310
+ console.log('User not found');
311
+ }
312
+
313
+ } finally {
314
+ await client.close();
315
+ }
316
+ }
317
+
318
+ findOneDocument().catch(console.error);
319
+ ```
320
+
321
+ **Find with Projection:**
322
+
323
+ ```javascript
324
+ async function findWithProjection() {
325
+ try {
326
+ await client.connect();
327
+ const database = client.db('sample_db');
328
+ const collection = database.collection('users');
329
+
330
+ const query = { age: { $gte: 25 } };
331
+ const options = {
332
+ projection: { _id: 0, name: 1, email: 1 }
333
+ };
334
+
335
+ const cursor = collection.find(query, options);
336
+ const results = await cursor.toArray();
337
+
338
+ console.log('Users (name and email only):', results);
339
+
340
+ } finally {
341
+ await client.close();
342
+ }
343
+ }
344
+
345
+ findWithProjection().catch(console.error);
346
+ ```
347
+
348
+ **Find with Sort, Limit, and Skip:**
349
+
350
+ ```javascript
351
+ async function findWithSortLimitSkip() {
352
+ try {
353
+ await client.connect();
354
+ const database = client.db('sample_db');
355
+ const collection = database.collection('users');
356
+
357
+ const cursor = collection.find({})
358
+ .sort({ age: -1 }) // Sort by age descending
359
+ .limit(10) // Limit to 10 results
360
+ .skip(5); // Skip first 5 results
361
+
362
+ const results = await cursor.toArray();
363
+
364
+ console.log('Sorted and paginated results:', results);
365
+
366
+ } finally {
367
+ await client.close();
368
+ }
369
+ }
370
+
371
+ findWithSortLimitSkip().catch(console.error);
372
+ ```
373
+
374
+ **Pagination Pattern:**
375
+
376
+ ```javascript
377
+ async function paginateDocuments(page = 1, pageSize = 10) {
378
+ try {
379
+ await client.connect();
380
+ const database = client.db('sample_db');
381
+ const collection = database.collection('users');
382
+
383
+ const skip = (page - 1) * pageSize;
384
+
385
+ const cursor = collection.find({})
386
+ .sort({ createdAt: -1 })
387
+ .skip(skip)
388
+ .limit(pageSize);
389
+
390
+ const documents = await cursor.toArray();
391
+ const total = await collection.countDocuments({});
392
+
393
+ return {
394
+ documents,
395
+ page,
396
+ pageSize,
397
+ totalPages: Math.ceil(total / pageSize),
398
+ totalDocuments: total
399
+ };
400
+
401
+ } finally {
402
+ await client.close();
403
+ }
404
+ }
405
+
406
+ paginateDocuments(1, 20).then(console.log).catch(console.error);
407
+ ```
408
+
409
+ **Cursor-Based Pagination (Better Performance):**
410
+
411
+ ```javascript
412
+ async function cursorPagination(lastId = null, pageSize = 10) {
413
+ try {
414
+ await client.connect();
415
+ const database = client.db('sample_db');
416
+ const collection = database.collection('users');
417
+
418
+ const query = lastId ? { _id: { $gt: lastId } } : {};
419
+
420
+ const cursor = collection.find(query)
421
+ .sort({ _id: 1 })
422
+ .limit(pageSize);
423
+
424
+ const documents = await cursor.toArray();
425
+
426
+ return {
427
+ documents,
428
+ nextCursor: documents.length > 0
429
+ ? documents[documents.length - 1]._id
430
+ : null
431
+ };
432
+
433
+ } finally {
434
+ await client.close();
435
+ }
436
+ }
437
+
438
+ cursorPagination(null, 20).then(console.log).catch(console.error);
439
+ ```
440
+
441
+ ### Update Documents
442
+
443
+ **Update One Document:**
444
+
445
+ ```javascript
446
+ async function updateOneDocument() {
447
+ try {
448
+ await client.connect();
449
+ const database = client.db('sample_db');
450
+ const collection = database.collection('users');
451
+
452
+ const filter = { email: 'john@example.com' };
453
+ const update = {
454
+ $set: { age: 31, updatedAt: new Date() }
455
+ };
456
+
457
+ const result = await collection.updateOne(filter, update);
458
+
459
+ console.log(`${result.matchedCount} document(s) matched the filter`);
460
+ console.log(`${result.modifiedCount} document(s) updated`);
461
+
462
+ } finally {
463
+ await client.close();
464
+ }
465
+ }
466
+
467
+ updateOneDocument().catch(console.error);
468
+ ```
469
+
470
+ **Update Multiple Documents:**
471
+
472
+ ```javascript
473
+ async function updateManyDocuments() {
474
+ try {
475
+ await client.connect();
476
+ const database = client.db('sample_db');
477
+ const collection = database.collection('users');
478
+
479
+ const filter = { age: { $lt: 30 } };
480
+ const update = {
481
+ $set: { category: 'young', updatedAt: new Date() }
482
+ };
483
+
484
+ const result = await collection.updateMany(filter, update);
485
+
486
+ console.log(`${result.matchedCount} document(s) matched`);
487
+ console.log(`${result.modifiedCount} document(s) updated`);
488
+
489
+ } finally {
490
+ await client.close();
491
+ }
492
+ }
493
+
494
+ updateManyDocuments().catch(console.error);
495
+ ```
496
+
497
+ **Update with Upsert:**
498
+
499
+ ```javascript
500
+ async function updateWithUpsert() {
501
+ try {
502
+ await client.connect();
503
+ const database = client.db('sample_db');
504
+ const collection = database.collection('users');
505
+
506
+ const filter = { email: 'newuser@example.com' };
507
+ const update = {
508
+ $set: {
509
+ name: 'New User',
510
+ email: 'newuser@example.com',
511
+ age: 22,
512
+ createdAt: new Date()
513
+ }
514
+ };
515
+
516
+ const options = { upsert: true };
517
+ const result = await collection.updateOne(filter, update, options);
518
+
519
+ if (result.upsertedId) {
520
+ console.log(`Document inserted with _id: ${result.upsertedId}`);
521
+ } else {
522
+ console.log(`${result.modifiedCount} document(s) updated`);
523
+ }
524
+
525
+ } finally {
526
+ await client.close();
527
+ }
528
+ }
529
+
530
+ updateWithUpsert().catch(console.error);
531
+ ```
532
+
533
+ **Update Operators:**
534
+
535
+ ```javascript
536
+ async function updateOperators() {
537
+ try {
538
+ await client.connect();
539
+ const database = client.db('sample_db');
540
+ const collection = database.collection('users');
541
+
542
+ const filter = { email: 'john@example.com' };
543
+ const update = {
544
+ $set: { status: 'active' },
545
+ $inc: { loginCount: 1 },
546
+ $push: { tags: 'premium' },
547
+ $currentDate: { lastModified: true }
548
+ };
549
+
550
+ const result = await collection.updateOne(filter, update);
551
+ console.log(`${result.modifiedCount} document(s) updated`);
552
+
553
+ } finally {
554
+ await client.close();
555
+ }
556
+ }
557
+
558
+ updateOperators().catch(console.error);
559
+ ```
560
+
561
+ **Replace Document:**
562
+
563
+ ```javascript
564
+ async function replaceDocument() {
565
+ try {
566
+ await client.connect();
567
+ const database = client.db('sample_db');
568
+ const collection = database.collection('users');
569
+
570
+ const filter = { email: 'john@example.com' };
571
+ const replacement = {
572
+ name: 'John Doe Updated',
573
+ email: 'john@example.com',
574
+ age: 31,
575
+ status: 'active',
576
+ updatedAt: new Date()
577
+ };
578
+
579
+ const result = await collection.replaceOne(filter, replacement);
580
+ console.log(`${result.modifiedCount} document(s) replaced`);
581
+
582
+ } finally {
583
+ await client.close();
584
+ }
585
+ }
586
+
587
+ replaceDocument().catch(console.error);
588
+ ```
589
+
590
+ **Find and Modify:**
591
+
592
+ ```javascript
593
+ async function findAndModify() {
594
+ try {
595
+ await client.connect();
596
+ const database = client.db('sample_db');
597
+ const collection = database.collection('users');
598
+
599
+ const filter = { email: 'john@example.com' };
600
+ const update = { $inc: { age: 1 } };
601
+ const options = {
602
+ returnDocument: 'after', // Return the updated document
603
+ upsert: false
604
+ };
605
+
606
+ const result = await collection.findOneAndUpdate(filter, update, options);
607
+
608
+ if (result) {
609
+ console.log('Updated document:', result);
610
+ }
611
+
612
+ } finally {
613
+ await client.close();
614
+ }
615
+ }
616
+
617
+ findAndModify().catch(console.error);
618
+ ```
619
+
620
+ ### Delete Documents
621
+
622
+ **Delete One Document:**
623
+
624
+ ```javascript
625
+ async function deleteOneDocument() {
626
+ try {
627
+ await client.connect();
628
+ const database = client.db('sample_db');
629
+ const collection = database.collection('users');
630
+
631
+ const filter = { email: 'john@example.com' };
632
+ const result = await collection.deleteOne(filter);
633
+
634
+ console.log(`${result.deletedCount} document(s) deleted`);
635
+
636
+ } finally {
637
+ await client.close();
638
+ }
639
+ }
640
+
641
+ deleteOneDocument().catch(console.error);
642
+ ```
643
+
644
+ **Delete Multiple Documents:**
645
+
646
+ ```javascript
647
+ async function deleteManyDocuments() {
648
+ try {
649
+ await client.connect();
650
+ const database = client.db('sample_db');
651
+ const collection = database.collection('users');
652
+
653
+ const filter = { age: { $lt: 18 } };
654
+ const result = await collection.deleteMany(filter);
655
+
656
+ console.log(`${result.deletedCount} document(s) deleted`);
657
+
658
+ } finally {
659
+ await client.close();
660
+ }
661
+ }
662
+
663
+ deleteManyDocuments().catch(console.error);
664
+ ```
665
+
666
+ **Find and Delete:**
667
+
668
+ ```javascript
669
+ async function findAndDelete() {
670
+ try {
671
+ await client.connect();
672
+ const database = client.db('sample_db');
673
+ const collection = database.collection('users');
674
+
675
+ const filter = { email: 'john@example.com' };
676
+ const options = {
677
+ sort: { createdAt: -1 }
678
+ };
679
+
680
+ const result = await collection.findOneAndDelete(filter, options);
681
+
682
+ if (result) {
683
+ console.log('Deleted document:', result);
684
+ } else {
685
+ console.log('No document found to delete');
686
+ }
687
+
688
+ } finally {
689
+ await client.close();
690
+ }
691
+ }
692
+
693
+ findAndDelete().catch(console.error);
694
+ ```
695
+
696
+ ## Aggregation Pipeline
697
+
698
+ **Basic Aggregation:**
699
+
700
+ ```javascript
701
+ async function basicAggregation() {
702
+ try {
703
+ await client.connect();
704
+ const database = client.db('sample_db');
705
+ const collection = database.collection('users');
706
+
707
+ const pipeline = [
708
+ { $match: { age: { $gte: 25 } } },
709
+ { $group: {
710
+ _id: '$status',
711
+ count: { $sum: 1 },
712
+ avgAge: { $avg: '$age' }
713
+ }
714
+ },
715
+ { $sort: { count: -1 } }
716
+ ];
717
+
718
+ const results = await collection.aggregate(pipeline).toArray();
719
+ console.log('Aggregation results:', results);
720
+
721
+ } finally {
722
+ await client.close();
723
+ }
724
+ }
725
+
726
+ basicAggregation().catch(console.error);
727
+ ```
728
+
729
+ **Advanced Aggregation with Multiple Stages:**
730
+
731
+ ```javascript
732
+ async function advancedAggregation() {
733
+ try {
734
+ await client.connect();
735
+ const database = client.db('sample_db');
736
+ const collection = database.collection('orders');
737
+
738
+ const pipeline = [
739
+ {
740
+ $match: {
741
+ status: 'completed',
742
+ createdAt: { $gte: new Date('2024-01-01') }
743
+ }
744
+ },
745
+ {
746
+ $group: {
747
+ _id: {
748
+ year: { $year: '$createdAt' },
749
+ month: { $month: '$createdAt' }
750
+ },
751
+ totalSales: { $sum: '$amount' },
752
+ orderCount: { $sum: 1 },
753
+ avgOrderValue: { $avg: '$amount' }
754
+ }
755
+ },
756
+ {
757
+ $sort: { '_id.year': 1, '_id.month': 1 }
758
+ },
759
+ {
760
+ $project: {
761
+ _id: 0,
762
+ year: '$_id.year',
763
+ month: '$_id.month',
764
+ totalSales: 1,
765
+ orderCount: 1,
766
+ avgOrderValue: { $round: ['$avgOrderValue', 2] }
767
+ }
768
+ }
769
+ ];
770
+
771
+ const results = await collection.aggregate(pipeline).toArray();
772
+ console.log('Sales report:', results);
773
+
774
+ } finally {
775
+ await client.close();
776
+ }
777
+ }
778
+
779
+ advancedAggregation().catch(console.error);
780
+ ```
781
+
782
+ **Aggregation with $lookup (Join):**
783
+
784
+ ```javascript
785
+ async function aggregationWithLookup() {
786
+ try {
787
+ await client.connect();
788
+ const database = client.db('sample_db');
789
+ const collection = database.collection('orders');
790
+
791
+ const pipeline = [
792
+ {
793
+ $lookup: {
794
+ from: 'users',
795
+ localField: 'userId',
796
+ foreignField: '_id',
797
+ as: 'userDetails'
798
+ }
799
+ },
800
+ {
801
+ $unwind: '$userDetails'
802
+ },
803
+ {
804
+ $project: {
805
+ orderNumber: 1,
806
+ amount: 1,
807
+ userName: '$userDetails.name',
808
+ userEmail: '$userDetails.email'
809
+ }
810
+ }
811
+ ];
812
+
813
+ const results = await collection.aggregate(pipeline).toArray();
814
+ console.log('Orders with user details:', results);
815
+
816
+ } finally {
817
+ await client.close();
818
+ }
819
+ }
820
+
821
+ aggregationWithLookup().catch(console.error);
822
+ ```
823
+
824
+ **Aggregation with $facet (Multiple Pipelines):**
825
+
826
+ ```javascript
827
+ async function aggregationWithFacet() {
828
+ try {
829
+ await client.connect();
830
+ const database = client.db('sample_db');
831
+ const collection = database.collection('products');
832
+
833
+ const pipeline = [
834
+ {
835
+ $facet: {
836
+ categoryCounts: [
837
+ { $group: { _id: '$category', count: { $sum: 1 } } },
838
+ { $sort: { count: -1 } }
839
+ ],
840
+ priceStats: [
841
+ {
842
+ $group: {
843
+ _id: null,
844
+ avgPrice: { $avg: '$price' },
845
+ minPrice: { $min: '$price' },
846
+ maxPrice: { $max: '$price' }
847
+ }
848
+ }
849
+ ],
850
+ topProducts: [
851
+ { $sort: { sales: -1 } },
852
+ { $limit: 5 },
853
+ { $project: { name: 1, sales: 1, price: 1 } }
854
+ ]
855
+ }
856
+ }
857
+ ];
858
+
859
+ const results = await collection.aggregate(pipeline).toArray();
860
+ console.log('Product analytics:', results[0]);
861
+
862
+ } finally {
863
+ await client.close();
864
+ }
865
+ }
866
+
867
+ aggregationWithFacet().catch(console.error);
868
+ ```
869
+
870
+ ## Indexes
871
+
872
+ **Create Single Field Index:**
873
+
874
+ ```javascript
875
+ async function createIndex() {
876
+ try {
877
+ await client.connect();
878
+ const database = client.db('sample_db');
879
+ const collection = database.collection('users');
880
+
881
+ const result = await collection.createIndex({ email: 1 });
882
+ console.log(`Index created: ${result}`);
883
+
884
+ } finally {
885
+ await client.close();
886
+ }
887
+ }
888
+
889
+ createIndex().catch(console.error);
890
+ ```
891
+
892
+ **Create Compound Index:**
893
+
894
+ ```javascript
895
+ async function createCompoundIndex() {
896
+ try {
897
+ await client.connect();
898
+ const database = client.db('sample_db');
899
+ const collection = database.collection('users');
900
+
901
+ const result = await collection.createIndex(
902
+ { lastName: 1, firstName: 1 }
903
+ );
904
+ console.log(`Compound index created: ${result}`);
905
+
906
+ } finally {
907
+ await client.close();
908
+ }
909
+ }
910
+
911
+ createCompoundIndex().catch(console.error);
912
+ ```
913
+
914
+ **Create Unique Index:**
915
+
916
+ ```javascript
917
+ async function createUniqueIndex() {
918
+ try {
919
+ await client.connect();
920
+ const database = client.db('sample_db');
921
+ const collection = database.collection('users');
922
+
923
+ const result = await collection.createIndex(
924
+ { email: 1 },
925
+ { unique: true }
926
+ );
927
+ console.log(`Unique index created: ${result}`);
928
+
929
+ } finally {
930
+ await client.close();
931
+ }
932
+ }
933
+
934
+ createUniqueIndex().catch(console.error);
935
+ ```
936
+
937
+ **Create Text Index:**
938
+
939
+ ```javascript
940
+ async function createTextIndex() {
941
+ try {
942
+ await client.connect();
943
+ const database = client.db('sample_db');
944
+ const collection = database.collection('articles');
945
+
946
+ const result = await collection.createIndex(
947
+ { title: 'text', content: 'text' }
948
+ );
949
+ console.log(`Text index created: ${result}`);
950
+
951
+ } finally {
952
+ await client.close();
953
+ }
954
+ }
955
+
956
+ createTextIndex().catch(console.error);
957
+ ```
958
+
959
+ **Text Search Query:**
960
+
961
+ ```javascript
962
+ async function textSearch() {
963
+ try {
964
+ await client.connect();
965
+ const database = client.db('sample_db');
966
+ const collection = database.collection('articles');
967
+
968
+ const query = { $text: { $search: 'mongodb tutorial' } };
969
+ const projection = { score: { $meta: 'textScore' } };
970
+
971
+ const cursor = collection
972
+ .find(query, { projection })
973
+ .sort({ score: { $meta: 'textScore' } });
974
+
975
+ const results = await cursor.toArray();
976
+ console.log('Search results:', results);
977
+
978
+ } finally {
979
+ await client.close();
980
+ }
981
+ }
982
+
983
+ textSearch().catch(console.error);
984
+ ```
985
+
986
+ **Create 2dsphere Index (Geospatial):**
987
+
988
+ ```javascript
989
+ async function createGeospatialIndex() {
990
+ try {
991
+ await client.connect();
992
+ const database = client.db('sample_db');
993
+ const collection = database.collection('locations');
994
+
995
+ const result = await collection.createIndex(
996
+ { location: '2dsphere' }
997
+ );
998
+ console.log(`Geospatial index created: ${result}`);
999
+
1000
+ } finally {
1001
+ await client.close();
1002
+ }
1003
+ }
1004
+
1005
+ createGeospatialIndex().catch(console.error);
1006
+ ```
1007
+
1008
+ **Geospatial Query ($near):**
1009
+
1010
+ ```javascript
1011
+ async function geospatialNearQuery() {
1012
+ try {
1013
+ await client.connect();
1014
+ const database = client.db('sample_db');
1015
+ const collection = database.collection('locations');
1016
+
1017
+ const query = {
1018
+ location: {
1019
+ $near: {
1020
+ $geometry: {
1021
+ type: 'Point',
1022
+ coordinates: [-73.9667, 40.78] // [longitude, latitude]
1023
+ },
1024
+ $maxDistance: 5000 // 5km in meters
1025
+ }
1026
+ }
1027
+ };
1028
+
1029
+ const results = await collection.find(query).limit(10).toArray();
1030
+ console.log('Nearby locations:', results);
1031
+
1032
+ } finally {
1033
+ await client.close();
1034
+ }
1035
+ }
1036
+
1037
+ geospatialNearQuery().catch(console.error);
1038
+ ```
1039
+
1040
+ **Geospatial Query ($geoWithin):**
1041
+
1042
+ ```javascript
1043
+ async function geospatialWithinQuery() {
1044
+ try {
1045
+ await client.connect();
1046
+ const database = client.db('sample_db');
1047
+ const collection = database.collection('locations');
1048
+
1049
+ const query = {
1050
+ location: {
1051
+ $geoWithin: {
1052
+ $geometry: {
1053
+ type: 'Polygon',
1054
+ coordinates: [[
1055
+ [-74.0, 40.7],
1056
+ [-73.9, 40.7],
1057
+ [-73.9, 40.8],
1058
+ [-74.0, 40.8],
1059
+ [-74.0, 40.7]
1060
+ ]]
1061
+ }
1062
+ }
1063
+ }
1064
+ };
1065
+
1066
+ const results = await collection.find(query).toArray();
1067
+ console.log('Locations within polygon:', results);
1068
+
1069
+ } finally {
1070
+ await client.close();
1071
+ }
1072
+ }
1073
+
1074
+ geospatialWithinQuery().catch(console.error);
1075
+ ```
1076
+
1077
+ **List Indexes:**
1078
+
1079
+ ```javascript
1080
+ async function listIndexes() {
1081
+ try {
1082
+ await client.connect();
1083
+ const database = client.db('sample_db');
1084
+ const collection = database.collection('users');
1085
+
1086
+ const indexes = await collection.listIndexes().toArray();
1087
+ console.log('Indexes:', indexes);
1088
+
1089
+ } finally {
1090
+ await client.close();
1091
+ }
1092
+ }
1093
+
1094
+ listIndexes().catch(console.error);
1095
+ ```
1096
+
1097
+ **Drop Index:**
1098
+
1099
+ ```javascript
1100
+ async function dropIndex() {
1101
+ try {
1102
+ await client.connect();
1103
+ const database = client.db('sample_db');
1104
+ const collection = database.collection('users');
1105
+
1106
+ const result = await collection.dropIndex('email_1');
1107
+ console.log('Index dropped:', result);
1108
+
1109
+ } finally {
1110
+ await client.close();
1111
+ }
1112
+ }
1113
+
1114
+ dropIndex().catch(console.error);
1115
+ ```
1116
+
1117
+ ## Bulk Write Operations
1118
+
1119
+ **Bulk Write with Mixed Operations:**
1120
+
1121
+ ```javascript
1122
+ async function bulkWrite() {
1123
+ try {
1124
+ await client.connect();
1125
+ const database = client.db('sample_db');
1126
+ const collection = database.collection('users');
1127
+
1128
+ const operations = [
1129
+ {
1130
+ insertOne: {
1131
+ document: { name: 'User 1', email: 'user1@example.com' }
1132
+ }
1133
+ },
1134
+ {
1135
+ updateOne: {
1136
+ filter: { email: 'john@example.com' },
1137
+ update: { $set: { status: 'active' } }
1138
+ }
1139
+ },
1140
+ {
1141
+ updateMany: {
1142
+ filter: { age: { $lt: 25 } },
1143
+ update: { $set: { category: 'young' } }
1144
+ }
1145
+ },
1146
+ {
1147
+ deleteOne: {
1148
+ filter: { email: 'old@example.com' }
1149
+ }
1150
+ },
1151
+ {
1152
+ replaceOne: {
1153
+ filter: { email: 'replace@example.com' },
1154
+ replacement: { name: 'Replaced', email: 'replace@example.com', age: 40 }
1155
+ }
1156
+ }
1157
+ ];
1158
+
1159
+ const result = await collection.bulkWrite(operations);
1160
+
1161
+ console.log(`${result.insertedCount} documents inserted`);
1162
+ console.log(`${result.modifiedCount} documents modified`);
1163
+ console.log(`${result.deletedCount} documents deleted`);
1164
+ console.log(`${result.upsertedCount} documents upserted`);
1165
+
1166
+ } finally {
1167
+ await client.close();
1168
+ }
1169
+ }
1170
+
1171
+ bulkWrite().catch(console.error);
1172
+ ```
1173
+
1174
+ **Ordered vs Unordered Bulk Write:**
1175
+
1176
+ ```javascript
1177
+ async function orderedVsUnorderedBulk() {
1178
+ try {
1179
+ await client.connect();
1180
+ const database = client.db('sample_db');
1181
+ const collection = database.collection('users');
1182
+
1183
+ const operations = [
1184
+ { insertOne: { document: { name: 'User A' } } },
1185
+ { insertOne: { document: { name: 'User B' } } }
1186
+ ];
1187
+
1188
+ // Ordered (default): stops on first error
1189
+ const orderedResult = await collection.bulkWrite(operations, { ordered: true });
1190
+
1191
+ // Unordered: continues on errors, may execute in parallel
1192
+ const unorderedResult = await collection.bulkWrite(operations, { ordered: false });
1193
+
1194
+ console.log('Ordered result:', orderedResult);
1195
+ console.log('Unordered result:', unorderedResult);
1196
+
1197
+ } finally {
1198
+ await client.close();
1199
+ }
1200
+ }
1201
+
1202
+ orderedVsUnorderedBulk().catch(console.error);
1203
+ ```
1204
+
1205
+ ## Transactions
1206
+
1207
+ **Transaction with Session (Convenient API):**
1208
+
1209
+ ```javascript
1210
+ async function transactionExample() {
1211
+ const session = client.startSession();
1212
+
1213
+ try {
1214
+ await client.connect();
1215
+ const database = client.db('sample_db');
1216
+
1217
+ const result = await session.withTransaction(async () => {
1218
+ const accounts = database.collection('accounts');
1219
+ const transactions = database.collection('transactions');
1220
+
1221
+ // Deduct from account A
1222
+ await accounts.updateOne(
1223
+ { accountId: 'A' },
1224
+ { $inc: { balance: -100 } },
1225
+ { session }
1226
+ );
1227
+
1228
+ // Add to account B
1229
+ await accounts.updateOne(
1230
+ { accountId: 'B' },
1231
+ { $inc: { balance: 100 } },
1232
+ { session }
1233
+ );
1234
+
1235
+ // Record transaction
1236
+ await transactions.insertOne(
1237
+ {
1238
+ from: 'A',
1239
+ to: 'B',
1240
+ amount: 100,
1241
+ timestamp: new Date()
1242
+ },
1243
+ { session }
1244
+ );
1245
+
1246
+ return 'Transaction completed';
1247
+ });
1248
+
1249
+ console.log(result);
1250
+
1251
+ } finally {
1252
+ await session.endSession();
1253
+ await client.close();
1254
+ }
1255
+ }
1256
+
1257
+ transactionExample().catch(console.error);
1258
+ ```
1259
+
1260
+ **Transaction with Core API (Manual Control):**
1261
+
1262
+ ```javascript
1263
+ async function manualTransaction() {
1264
+ const session = client.startSession();
1265
+
1266
+ try {
1267
+ await client.connect();
1268
+ const database = client.db('sample_db');
1269
+ const accounts = database.collection('accounts');
1270
+
1271
+ // Start transaction
1272
+ session.startTransaction({
1273
+ readConcern: { level: 'snapshot' },
1274
+ writeConcern: { w: 'majority' }
1275
+ });
1276
+
1277
+ try {
1278
+ // Perform operations within transaction
1279
+ await accounts.updateOne(
1280
+ { accountId: 'A' },
1281
+ { $inc: { balance: -100 } },
1282
+ { session }
1283
+ );
1284
+
1285
+ await accounts.updateOne(
1286
+ { accountId: 'B' },
1287
+ { $inc: { balance: 100 } },
1288
+ { session }
1289
+ );
1290
+
1291
+ // Commit transaction
1292
+ await session.commitTransaction();
1293
+ console.log('Transaction committed');
1294
+
1295
+ } catch (error) {
1296
+ // Abort transaction on error
1297
+ await session.abortTransaction();
1298
+ console.error('Transaction aborted:', error);
1299
+ throw error;
1300
+ }
1301
+
1302
+ } finally {
1303
+ await session.endSession();
1304
+ await client.close();
1305
+ }
1306
+ }
1307
+
1308
+ manualTransaction().catch(console.error);
1309
+ ```
1310
+
1311
+ **Transaction with Retry Logic:**
1312
+
1313
+ ```javascript
1314
+ async function transactionWithRetry() {
1315
+ const session = client.startSession();
1316
+
1317
+ async function runTransactionWithRetry(txnFunc, session) {
1318
+ while (true) {
1319
+ try {
1320
+ return await txnFunc(session);
1321
+ } catch (error) {
1322
+ if (error.hasErrorLabel('TransientTransactionError')) {
1323
+ console.log('TransientTransactionError, retrying transaction...');
1324
+ continue;
1325
+ }
1326
+ throw error;
1327
+ }
1328
+ }
1329
+ }
1330
+
1331
+ async function commitWithRetry(session) {
1332
+ while (true) {
1333
+ try {
1334
+ await session.commitTransaction();
1335
+ console.log('Transaction committed');
1336
+ break;
1337
+ } catch (error) {
1338
+ if (error.hasErrorLabel('UnknownTransactionCommitResult')) {
1339
+ console.log('UnknownTransactionCommitResult, retrying commit...');
1340
+ continue;
1341
+ }
1342
+ throw error;
1343
+ }
1344
+ }
1345
+ }
1346
+
1347
+ try {
1348
+ await client.connect();
1349
+ const database = client.db('sample_db');
1350
+
1351
+ await runTransactionWithRetry(async (session) => {
1352
+ session.startTransaction();
1353
+
1354
+ const accounts = database.collection('accounts');
1355
+
1356
+ await accounts.updateOne(
1357
+ { accountId: 'A' },
1358
+ { $inc: { balance: -50 } },
1359
+ { session }
1360
+ );
1361
+
1362
+ await accounts.updateOne(
1363
+ { accountId: 'B' },
1364
+ { $inc: { balance: 50 } },
1365
+ { session }
1366
+ );
1367
+
1368
+ await commitWithRetry(session);
1369
+ }, session);
1370
+
1371
+ } finally {
1372
+ await session.endSession();
1373
+ await client.close();
1374
+ }
1375
+ }
1376
+
1377
+ transactionWithRetry().catch(console.error);
1378
+ ```
1379
+
1380
+ ## Change Streams
1381
+
1382
+ **Watch Collection for Changes:**
1383
+
1384
+ ```javascript
1385
+ async function watchCollection() {
1386
+ try {
1387
+ await client.connect();
1388
+ const database = client.db('sample_db');
1389
+ const collection = database.collection('users');
1390
+
1391
+ const changeStream = collection.watch();
1392
+
1393
+ console.log('Watching for changes...');
1394
+
1395
+ changeStream.on('change', (change) => {
1396
+ console.log('Change detected:', change);
1397
+ });
1398
+
1399
+ changeStream.on('error', (error) => {
1400
+ console.error('Change stream error:', error);
1401
+ });
1402
+
1403
+ // Keep the connection open
1404
+ // In production, you'd handle this differently
1405
+
1406
+ } catch (error) {
1407
+ console.error(error);
1408
+ }
1409
+ }
1410
+
1411
+ watchCollection().catch(console.error);
1412
+ ```
1413
+
1414
+ **Watch with Filter Pipeline:**
1415
+
1416
+ ```javascript
1417
+ async function watchWithFilter() {
1418
+ try {
1419
+ await client.connect();
1420
+ const database = client.db('sample_db');
1421
+ const collection = database.collection('users');
1422
+
1423
+ const pipeline = [
1424
+ {
1425
+ $match: {
1426
+ 'operationType': { $in: ['insert', 'update'] },
1427
+ 'fullDocument.age': { $gte: 18 }
1428
+ }
1429
+ }
1430
+ ];
1431
+
1432
+ const changeStream = collection.watch(pipeline);
1433
+
1434
+ console.log('Watching for adult user changes...');
1435
+
1436
+ for await (const change of changeStream) {
1437
+ console.log('Change:', change);
1438
+
1439
+ if (change.operationType === 'insert') {
1440
+ console.log('New user inserted:', change.fullDocument);
1441
+ } else if (change.operationType === 'update') {
1442
+ console.log('User updated:', change.documentKey);
1443
+ }
1444
+ }
1445
+
1446
+ } catch (error) {
1447
+ console.error(error);
1448
+ }
1449
+ }
1450
+
1451
+ watchWithFilter().catch(console.error);
1452
+ ```
1453
+
1454
+ **Watch Database for Changes:**
1455
+
1456
+ ```javascript
1457
+ async function watchDatabase() {
1458
+ try {
1459
+ await client.connect();
1460
+ const database = client.db('sample_db');
1461
+
1462
+ const changeStream = database.watch();
1463
+
1464
+ console.log('Watching database for changes...');
1465
+
1466
+ changeStream.on('change', (change) => {
1467
+ console.log(`Change in collection ${change.ns.coll}:`, change);
1468
+ });
1469
+
1470
+ } catch (error) {
1471
+ console.error(error);
1472
+ }
1473
+ }
1474
+
1475
+ watchDatabase().catch(console.error);
1476
+ ```
1477
+
1478
+ ## ObjectId Utilities
1479
+
1480
+ **Working with ObjectId:**
1481
+
1482
+ ```javascript
1483
+ import { ObjectId } from 'mongodb';
1484
+
1485
+ async function objectIdExamples() {
1486
+ try {
1487
+ await client.connect();
1488
+ const database = client.db('sample_db');
1489
+ const collection = database.collection('users');
1490
+
1491
+ // Generate new ObjectId
1492
+ const newId = new ObjectId();
1493
+ console.log('New ObjectId:', newId.toString());
1494
+
1495
+ // Insert with custom ObjectId
1496
+ await collection.insertOne({
1497
+ _id: new ObjectId(),
1498
+ name: 'User with custom ID'
1499
+ });
1500
+
1501
+ // Find by ObjectId string
1502
+ const userId = '507f1f77bcf86cd799439011';
1503
+ const user = await collection.findOne({
1504
+ _id: new ObjectId(userId)
1505
+ });
1506
+
1507
+ // Get timestamp from ObjectId
1508
+ if (user) {
1509
+ const timestamp = user._id.getTimestamp();
1510
+ console.log('Document created at:', timestamp);
1511
+ }
1512
+
1513
+ // Validate ObjectId
1514
+ const isValid = ObjectId.isValid('507f1f77bcf86cd799439011');
1515
+ console.log('Is valid ObjectId:', isValid);
1516
+
1517
+ } finally {
1518
+ await client.close();
1519
+ }
1520
+ }
1521
+
1522
+ objectIdExamples().catch(console.error);
1523
+ ```
1524
+
1525
+ ## Error Handling
1526
+
1527
+ **Comprehensive Error Handling:**
1528
+
1529
+ ```javascript
1530
+ import { MongoClient, MongoServerError } from 'mongodb';
1531
+
1532
+ async function errorHandlingExample() {
1533
+ const client = new MongoClient(process.env.MONGODB_URI);
1534
+
1535
+ try {
1536
+ await client.connect();
1537
+ const database = client.db('sample_db');
1538
+ const collection = database.collection('users');
1539
+
1540
+ // Attempt operation
1541
+ await collection.insertOne({
1542
+ email: 'duplicate@example.com'
1543
+ });
1544
+
1545
+ } catch (error) {
1546
+ if (error instanceof MongoServerError) {
1547
+ switch (error.code) {
1548
+ case 11000:
1549
+ console.error('Duplicate key error:', error.message);
1550
+ break;
1551
+ case 121:
1552
+ console.error('Document validation failed:', error.message);
1553
+ break;
1554
+ default:
1555
+ console.error('MongoDB server error:', error.message);
1556
+ }
1557
+ } else if (error.name === 'MongoNetworkError') {
1558
+ console.error('Network error - cannot connect to MongoDB:', error.message);
1559
+ } else if (error.name === 'MongoParseError') {
1560
+ console.error('Invalid connection string:', error.message);
1561
+ } else {
1562
+ console.error('Unexpected error:', error);
1563
+ }
1564
+ } finally {
1565
+ await client.close();
1566
+ }
1567
+ }
1568
+
1569
+ errorHandlingExample().catch(console.error);
1570
+ ```
1571
+
1572
+ **Retry Logic for Transient Errors:**
1573
+
1574
+ ```javascript
1575
+ async function retryOperation(operation, maxRetries = 3) {
1576
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
1577
+ try {
1578
+ return await operation();
1579
+ } catch (error) {
1580
+ if (attempt === maxRetries) {
1581
+ throw error;
1582
+ }
1583
+
1584
+ const isRetryable =
1585
+ error.name === 'MongoNetworkError' ||
1586
+ error.code === 'ETIMEDOUT' ||
1587
+ error.code === 'ECONNRESET';
1588
+
1589
+ if (!isRetryable) {
1590
+ throw error;
1591
+ }
1592
+
1593
+ const delay = Math.pow(2, attempt) * 1000;
1594
+ console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
1595
+ await new Promise(resolve => setTimeout(resolve, delay));
1596
+ }
1597
+ }
1598
+ }
1599
+
1600
+ async function useRetryLogic() {
1601
+ const client = new MongoClient(process.env.MONGODB_URI);
1602
+
1603
+ try {
1604
+ await retryOperation(async () => {
1605
+ await client.connect();
1606
+ const database = client.db('sample_db');
1607
+ const collection = database.collection('users');
1608
+
1609
+ return await collection.findOne({ email: 'test@example.com' });
1610
+ });
1611
+
1612
+ } finally {
1613
+ await client.close();
1614
+ }
1615
+ }
1616
+
1617
+ useRetryLogic().catch(console.error);
1618
+ ```
1619
+
1620
+ ## Query Operators
1621
+
1622
+ **Comparison Operators:**
1623
+
1624
+ ```javascript
1625
+ async function comparisonOperators() {
1626
+ try {
1627
+ await client.connect();
1628
+ const database = client.db('sample_db');
1629
+ const collection = database.collection('products');
1630
+
1631
+ // $eq (equal)
1632
+ const equal = await collection.find({ price: { $eq: 99 } }).toArray();
1633
+
1634
+ // $ne (not equal)
1635
+ const notEqual = await collection.find({ status: { $ne: 'discontinued' } }).toArray();
1636
+
1637
+ // $gt, $gte (greater than, greater than or equal)
1638
+ const greaterThan = await collection.find({ price: { $gt: 50 } }).toArray();
1639
+ const greaterOrEqual = await collection.find({ stock: { $gte: 100 } }).toArray();
1640
+
1641
+ // $lt, $lte (less than, less than or equal)
1642
+ const lessThan = await collection.find({ price: { $lt: 100 } }).toArray();
1643
+ const lessOrEqual = await collection.find({ rating: { $lte: 3 } }).toArray();
1644
+
1645
+ // $in (in array)
1646
+ const inArray = await collection.find({
1647
+ category: { $in: ['electronics', 'computers'] }
1648
+ }).toArray();
1649
+
1650
+ // $nin (not in array)
1651
+ const notInArray = await collection.find({
1652
+ status: { $nin: ['discontinued', 'out-of-stock'] }
1653
+ }).toArray();
1654
+
1655
+ console.log('Query results:', equal, notEqual, greaterThan);
1656
+
1657
+ } finally {
1658
+ await client.close();
1659
+ }
1660
+ }
1661
+
1662
+ comparisonOperators().catch(console.error);
1663
+ ```
1664
+
1665
+ **Logical Operators:**
1666
+
1667
+ ```javascript
1668
+ async function logicalOperators() {
1669
+ try {
1670
+ await client.connect();
1671
+ const database = client.db('sample_db');
1672
+ const collection = database.collection('products');
1673
+
1674
+ // $and
1675
+ const andQuery = await collection.find({
1676
+ $and: [
1677
+ { price: { $lt: 100 } },
1678
+ { stock: { $gt: 0 } }
1679
+ ]
1680
+ }).toArray();
1681
+
1682
+ // $or
1683
+ const orQuery = await collection.find({
1684
+ $or: [
1685
+ { category: 'electronics' },
1686
+ { featured: true }
1687
+ ]
1688
+ }).toArray();
1689
+
1690
+ // $not
1691
+ const notQuery = await collection.find({
1692
+ price: { $not: { $gt: 100 } }
1693
+ }).toArray();
1694
+
1695
+ // $nor
1696
+ const norQuery = await collection.find({
1697
+ $nor: [
1698
+ { status: 'discontinued' },
1699
+ { stock: 0 }
1700
+ ]
1701
+ }).toArray();
1702
+
1703
+ console.log('Logical query results:', andQuery.length, orQuery.length);
1704
+
1705
+ } finally {
1706
+ await client.close();
1707
+ }
1708
+ }
1709
+
1710
+ logicalOperators().catch(console.error);
1711
+ ```
1712
+
1713
+ **Element Operators:**
1714
+
1715
+ ```javascript
1716
+ async function elementOperators() {
1717
+ try {
1718
+ await client.connect();
1719
+ const database = client.db('sample_db');
1720
+ const collection = database.collection('users');
1721
+
1722
+ // $exists
1723
+ const hasPhone = await collection.find({
1724
+ phone: { $exists: true }
1725
+ }).toArray();
1726
+
1727
+ // $type
1728
+ const stringEmails = await collection.find({
1729
+ email: { $type: 'string' }
1730
+ }).toArray();
1731
+
1732
+ console.log('Element query results:', hasPhone.length, stringEmails.length);
1733
+
1734
+ } finally {
1735
+ await client.close();
1736
+ }
1737
+ }
1738
+
1739
+ elementOperators().catch(console.error);
1740
+ ```
1741
+
1742
+ **Array Operators:**
1743
+
1744
+ ```javascript
1745
+ async function arrayOperators() {
1746
+ try {
1747
+ await client.connect();
1748
+ const database = client.db('sample_db');
1749
+ const collection = database.collection('users');
1750
+
1751
+ // $all
1752
+ const allTags = await collection.find({
1753
+ tags: { $all: ['premium', 'verified'] }
1754
+ }).toArray();
1755
+
1756
+ // $elemMatch
1757
+ const elemMatch = await collection.find({
1758
+ scores: { $elemMatch: { $gte: 80, $lt: 90 } }
1759
+ }).toArray();
1760
+
1761
+ // $size
1762
+ const exactSize = await collection.find({
1763
+ tags: { $size: 3 }
1764
+ }).toArray();
1765
+
1766
+ console.log('Array query results:', allTags.length, elemMatch.length);
1767
+
1768
+ } finally {
1769
+ await client.close();
1770
+ }
1771
+ }
1772
+
1773
+ arrayOperators().catch(console.error);
1774
+ ```
1775
+
1776
+ ## Advanced Patterns
1777
+
1778
+ **Connection Pooling:**
1779
+
1780
+ ```javascript
1781
+ import { MongoClient } from 'mongodb';
1782
+
1783
+ const uri = process.env.MONGODB_URI;
1784
+
1785
+ const client = new MongoClient(uri, {
1786
+ maxPoolSize: 50,
1787
+ minPoolSize: 10,
1788
+ maxIdleTimeMS: 30000,
1789
+ waitQueueTimeoutMS: 5000
1790
+ });
1791
+
1792
+ let isConnected = false;
1793
+
1794
+ async function getDatabase() {
1795
+ if (!isConnected) {
1796
+ await client.connect();
1797
+ isConnected = true;
1798
+ }
1799
+ return client.db('sample_db');
1800
+ }
1801
+
1802
+ export { getDatabase, client };
1803
+ ```
1804
+
1805
+ **Database and Collection Management:**
1806
+
1807
+ ```javascript
1808
+ async function databaseManagement() {
1809
+ try {
1810
+ await client.connect();
1811
+
1812
+ // List databases
1813
+ const adminDb = client.db().admin();
1814
+ const dbList = await adminDb.listDatabases();
1815
+ console.log('Databases:', dbList.databases);
1816
+
1817
+ // List collections
1818
+ const database = client.db('sample_db');
1819
+ const collections = await database.listCollections().toArray();
1820
+ console.log('Collections:', collections);
1821
+
1822
+ // Create collection with options
1823
+ await database.createCollection('newCollection', {
1824
+ validator: {
1825
+ $jsonSchema: {
1826
+ bsonType: 'object',
1827
+ required: ['name', 'email'],
1828
+ properties: {
1829
+ name: {
1830
+ bsonType: 'string',
1831
+ description: 'must be a string and is required'
1832
+ },
1833
+ email: {
1834
+ bsonType: 'string',
1835
+ pattern: '^.+@.+$',
1836
+ description: 'must be a valid email'
1837
+ }
1838
+ }
1839
+ }
1840
+ }
1841
+ });
1842
+
1843
+ // Drop collection
1844
+ // await database.collection('oldCollection').drop();
1845
+
1846
+ } finally {
1847
+ await client.close();
1848
+ }
1849
+ }
1850
+
1851
+ databaseManagement().catch(console.error);
1852
+ ```
1853
+
1854
+ **Schema Validation:**
1855
+
1856
+ ```javascript
1857
+ async function addSchemaValidation() {
1858
+ try {
1859
+ await client.connect();
1860
+ const database = client.db('sample_db');
1861
+
1862
+ await database.command({
1863
+ collMod: 'users',
1864
+ validator: {
1865
+ $jsonSchema: {
1866
+ bsonType: 'object',
1867
+ required: ['name', 'email', 'age'],
1868
+ properties: {
1869
+ name: {
1870
+ bsonType: 'string',
1871
+ description: 'must be a string and is required'
1872
+ },
1873
+ email: {
1874
+ bsonType: 'string',
1875
+ pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
1876
+ description: 'must be a valid email and is required'
1877
+ },
1878
+ age: {
1879
+ bsonType: 'int',
1880
+ minimum: 0,
1881
+ maximum: 150,
1882
+ description: 'must be an integer between 0 and 150'
1883
+ },
1884
+ status: {
1885
+ enum: ['active', 'inactive', 'suspended'],
1886
+ description: 'can only be one of the enum values'
1887
+ }
1888
+ }
1889
+ }
1890
+ },
1891
+ validationLevel: 'moderate',
1892
+ validationAction: 'error'
1893
+ });
1894
+
1895
+ console.log('Schema validation added');
1896
+
1897
+ } finally {
1898
+ await client.close();
1899
+ }
1900
+ }
1901
+
1902
+ addSchemaValidation().catch(console.error);
1903
+ ```
1904
+
1905
+ **Time Series Collections:**
1906
+
1907
+ ```javascript
1908
+ async function createTimeSeriesCollection() {
1909
+ try {
1910
+ await client.connect();
1911
+ const database = client.db('sample_db');
1912
+
1913
+ await database.createCollection('sensor_data', {
1914
+ timeseries: {
1915
+ timeField: 'timestamp',
1916
+ metaField: 'sensorId',
1917
+ granularity: 'seconds'
1918
+ }
1919
+ });
1920
+
1921
+ const collection = database.collection('sensor_data');
1922
+
1923
+ // Insert time series data
1924
+ await collection.insertMany([
1925
+ {
1926
+ sensorId: 'sensor1',
1927
+ timestamp: new Date('2024-01-01T00:00:00Z'),
1928
+ temperature: 22.5,
1929
+ humidity: 60
1930
+ },
1931
+ {
1932
+ sensorId: 'sensor1',
1933
+ timestamp: new Date('2024-01-01T00:01:00Z'),
1934
+ temperature: 22.7,
1935
+ humidity: 59
1936
+ }
1937
+ ]);
1938
+
1939
+ console.log('Time series data inserted');
1940
+
1941
+ } finally {
1942
+ await client.close();
1943
+ }
1944
+ }
1945
+
1946
+ createTimeSeriesCollection().catch(console.error);
1947
+ ```
1948
+
1949
+ **Read and Write Concerns:**
1950
+
1951
+ ```javascript
1952
+ async function readWriteConcerns() {
1953
+ try {
1954
+ await client.connect();
1955
+ const database = client.db('sample_db');
1956
+ const collection = database.collection('users');
1957
+
1958
+ // Write concern
1959
+ const insertResult = await collection.insertOne(
1960
+ { name: 'John', email: 'john@example.com' },
1961
+ {
1962
+ writeConcern: {
1963
+ w: 'majority',
1964
+ j: true,
1965
+ wtimeout: 5000
1966
+ }
1967
+ }
1968
+ );
1969
+
1970
+ // Read concern
1971
+ const findResult = await collection.findOne(
1972
+ { email: 'john@example.com' },
1973
+ {
1974
+ readConcern: { level: 'majority' }
1975
+ }
1976
+ );
1977
+
1978
+ console.log('Insert result:', insertResult);
1979
+ console.log('Find result:', findResult);
1980
+
1981
+ } finally {
1982
+ await client.close();
1983
+ }
1984
+ }
1985
+
1986
+ readWriteConcerns().catch(console.error);
1987
+ ```
1988
+
1989
+ **Count Documents:**
1990
+
1991
+ ```javascript
1992
+ async function countExamples() {
1993
+ try {
1994
+ await client.connect();
1995
+ const database = client.db('sample_db');
1996
+ const collection = database.collection('users');
1997
+
1998
+ // Count all documents
1999
+ const totalCount = await collection.countDocuments({});
2000
+ console.log('Total documents:', totalCount);
2001
+
2002
+ // Count with filter
2003
+ const activeCount = await collection.countDocuments({ status: 'active' });
2004
+ console.log('Active users:', activeCount);
2005
+
2006
+ // Estimated count (faster but less accurate)
2007
+ const estimatedCount = await collection.estimatedDocumentCount();
2008
+ console.log('Estimated count:', estimatedCount);
2009
+
2010
+ } finally {
2011
+ await client.close();
2012
+ }
2013
+ }
2014
+
2015
+ countExamples().catch(console.error);
2016
+ ```
2017
+
2018
+ **Distinct Values:**
2019
+
2020
+ ```javascript
2021
+ async function distinctValues() {
2022
+ try {
2023
+ await client.connect();
2024
+ const database = client.db('sample_db');
2025
+ const collection = database.collection('users');
2026
+
2027
+ // Get distinct values
2028
+ const cities = await collection.distinct('city');
2029
+ console.log('Distinct cities:', cities);
2030
+
2031
+ // Get distinct values with filter
2032
+ const activeCities = await collection.distinct('city', { status: 'active' });
2033
+ console.log('Cities with active users:', activeCities);
2034
+
2035
+ } finally {
2036
+ await client.close();
2037
+ }
2038
+ }
2039
+
2040
+ distinctValues().catch(console.error);
2041
+ ```