{"id":4438,"date":"2025-08-09T13:52:57","date_gmt":"2025-08-09T13:52:57","guid":{"rendered":"https:\/\/uplatz.com\/blog\/?p=4438"},"modified":"2025-08-09T13:52:57","modified_gmt":"2025-08-09T13:52:57","slug":"mongodb-pocket-book","status":"publish","type":"post","link":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/","title":{"rendered":"MongoDB Pocket Book"},"content":{"rendered":"<p><!-- MongoDB Pocket Book \u2014 Uplatz (50 Cards, Wide Layout, Readable Code, Scoped Styles) --><\/p>\n<div style=\"margin:16px 0;\">\n<style>\n    .wp-mongo-pb { font-family: Arial, sans-serif; max-width: 1320px; margin:0 auto; }\n    .wp-mongo-pb .heading{\n      background: linear-gradient(135deg, #e8f5e9, #e0f2fe); \/* light green -> light blue *\/\n      color:#0f172a; padding:22px 24px; border-radius:14px;\n      text-align:center; margin-bottom:18px; box-shadow:0 8px 20px rgba(0,0,0,.08);\n      border:1px solid #cbd5e1;\n    }\n    .wp-mongo-pb .heading h2{ margin:0; font-size:2.1rem; letter-spacing:.2px; }\n    .wp-mongo-pb .heading p{ margin:6px 0 0; font-size:1.02rem; opacity:.9; }<\/p>\n<p>    \/* Wide, dense grid *\/\n    .wp-mongo-pb .grid{\n      display:grid; gap:14px;\n      grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n    }\n    @media (min-width:1200px){\n      .wp-mongo-pb .grid{ grid-template-columns: repeat(3, 1fr); }\n    }<\/p>\n<p>    .wp-mongo-pb .section-title{\n      grid-column:1\/-1; background:#f8fafc; border-left:8px solid #16a34a; \/* mongo green-ish *\/\n      padding:12px 16px; border-radius:10px; font-weight:700; color:#0f172a; font-size:1.08rem;\n      box-shadow:0 2px 8px rgba(0,0,0,.05); border:1px solid #e2e8f0;\n    }\n    .wp-mongo-pb .card{\n      background:#ffffff; border-left:6px solid #16a34a;\n      padding:18px; border-radius:12px;\n      box-shadow:0 6px 14px rgba(0,0,0,.06);\n      transition:transform .12s ease, box-shadow .12s ease;\n      border:1px solid #e5e7eb;\n    }\n    .wp-mongo-pb .card:hover{ transform: translateY(-3px); box-shadow:0 10px 22px rgba(0,0,0,.08); }\n    .wp-mongo-pb .card h3{ margin:0 0 10px; font-size:1.12rem; color:#0f172a; }\n    .wp-mongo-pb .card p{ margin:0; font-size:.96rem; color:#334155; line-height:1.62; }<\/p>\n<p>    \/* Color helpers *\/\n    .bg-green{ border-left-color:#16a34a !important; background:#f0fdf4 !important; }\n    .bg-blue { border-left-color:#0ea5e9 !important; background:#e0f2fe !important; }\n    .bg-amber{ border-left-color:#f59e0b !important; background:#fffbeb !important; }\n    .bg-violet{ border-left-color:#8b5cf6 !important; background:#f5f3ff !important; }\n    .bg-rose{ border-left-color:#ef4444 !important; background:#fff1f2 !important; }\n    .bg-cyan{ border-left-color:#06b6d4 !important; background:#ecfeff !important; }\n    .bg-lime{ border-left-color:#22c55e !important; background:#ecfdf5 !important; }\n    .bg-orange{ border-left-color:#f97316 !important; background:#fff7ed !important; }\n    .bg-indigo{ border-left-color:#6366f1 !important; background:#eef2ff !important; }\n    .bg-slate{ border-left-color:#334155 !important; background:#f8fafc !important; }<\/p>\n<p>    \/* Code & utils *\/\n    .tight ul{ margin:0; padding-left:18px; }\n    .tight li{ margin:4px 0; }\n    .mono{ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }\n    .wp-mongo-pb code{ background:#f1f5f9; padding:0 4px; border-radius:4px; border:1px solid #e2e8f0; }\n    .wp-mongo-pb pre{\n      background:#f5f5f5; color:#111827; border:1px solid #e5e7eb;\n      padding:12px; border-radius:8px; overflow:auto; font-size:.92rem; line-height:1.55;\n    }\n    .q{font-weight:700;}\n    .qa p{ margin:8px 0; }\n  <\/style>\n<div class=\"wp-mongo-pb\">\n<div class=\"heading\">\n<h2>MongoDB Pocket Book \u2014 Uplatz<\/h2>\n<p>50 in-depth cards \u2022 Wide layout \u2022 Readable examples \u2022 20-Q interview block included<\/p>\n<\/p><\/div>\n<div class=\"grid\">\n      <!-- ===================== SECTION 1: FOUNDATIONS (1\u201310) ===================== --><\/p>\n<div class=\"section-title\">Section 1 \u2014 Foundations<\/div>\n<div class=\"card bg-green\">\n<h3>1) What is MongoDB?<\/h3>\n<p>MongoDB is a document-oriented NoSQL database storing JSON-like BSON documents. It favors flexible schemas, horizontal scaling via sharding, and rich secondary indexes, with a powerful aggregation framework and transactions (multi-document ACID).<\/p>\n<pre><code class=\"mono\"># shell\r\nmongosh \"mongodb:\/\/localhost:27017\"<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-blue\">\n<h3>2) Core Concepts<\/h3>\n<p>Hierarchy: Database \u2192 Collections \u2192 Documents. Each document has an <code>_id<\/code> primary key (ObjectId by default). Schemas are dynamic unless validated. CRUD via drivers or <code>mongosh<\/code>.<\/p>\n<pre><code class=\"mono\">db.users.insertOne({ name:\"Ava\", age:29, skills:[\"mongo\",\"node\"] })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-amber\">\n<h3>3) BSON &#038; Types<\/h3>\n<p>BSON adds types beyond JSON: <code>ObjectId<\/code>, <code>Date<\/code>, <code>Decimal128<\/code>, <code>Binary<\/code>, <code>Timestamp<\/code>. Choose <code>Decimal128<\/code> for precise monetary values; <code>Date<\/code> for ISO dates stored in UTC.<\/p>\n<pre><code class=\"mono\">db.tx.insertOne({ amount: NumberDecimal(\"12.34\"), ts: new Date() })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-violet\">\n<h3>4) Read &#038; Write Concerns<\/h3>\n<p><b>Write concern<\/b> controls durability (<code>w<\/code>, <code>j<\/code>, <code>wtimeout<\/code>). <b>Read concern<\/b> controls consistency (<code>local<\/code>, <code>majority<\/code>, <code>linearizable<\/code>, <code>snapshot<\/code> in txns). Tune per operation.<\/p>\n<pre><code class=\"mono\">db.orders.insertOne(doc, { writeConcern: { w:\"majority\", j:true } })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-rose\">\n<h3>5) Replica Sets<\/h3>\n<p>Replica set = primary + secondaries for HA. Primary handles writes; secondaries replicate via the oplog. Elections pick a new primary on failure. Reads can target secondaries with read preferences.<\/p>\n<pre><code class=\"mono\">rs.initiate({ _id:\"rs0\", members:[{_id:0,host:\"n1\"},{_id:1,host:\"n2\"}] })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-cyan\">\n<h3>6) Sharding<\/h3>\n<p>Sharding distributes data across shards (each a replica set). A <code>mongos<\/code> router routes queries. Pick a good shard key (high cardinality, good distribution). Zones can pin data by range for locality\/regulations.<\/p>\n<pre><code class=\"mono\">sh.enableSharding(\"shop\"); sh.shardCollection(\"shop.orders\",{ region:1, _id:1 })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-lime\">\n<h3>7) Storage Engine (WiredTiger)<\/h3>\n<p>WiredTiger provides document-level concurrency, compression, checkpoints, and journaling. Configure cache size (~50% RAM default). Compression reduces I\/O at slight CPU cost.<\/p>\n<pre><code class=\"mono\">storage.wiredTiger.engineConfig.cacheSizeGB: 8<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-orange\">\n<h3>8) Index Basics<\/h3>\n<p>Indexes speed reads. Default <code>_id<\/code> index exists. Create compound indexes for common query patterns; order matters. Cardinality, selectivity, and sort patterns drive index design.<\/p>\n<pre><code class=\"mono\">db.users.createIndex({ email:1 }, { unique:true })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-indigo\">\n<h3>9) Aggregation Framework<\/h3>\n<p>Pipeline stages (<code>$match<\/code>, <code>$group<\/code>, <code>$project<\/code>, <code>$sort<\/code>, <code>$lookup<\/code>, <code>$facet<\/code>) enable analytical queries without ETL. Many ops push down to indexes.<\/p>\n<pre><code class=\"mono\">db.sales.aggregate([{ $match:{region:\"EU\"} },{ $group:{ _id:\"$sku\", rev:{ $sum:\"$amount\"} } }])<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-slate\">\n<h3>10) Q&amp;A \u2014 \u201cMongoDB vs RDBMS?\u201d<\/h3>\n<p><span class=\"q\">Answer:<\/span> MongoDB trades rigid schemas and joins for flexible documents, fast iteration, and horizontal scale. It supports ACID transactions when needed but shines with denormalized schemas optimized for app reads.<\/p>\n<\/p><\/div>\n<p>      <!-- ===================== SECTION 2: DATA MODEL & CRUD (11\u201320) ===================== --><\/p>\n<div class=\"section-title\">Section 2 \u2014 Data Modeling &#038; CRUD<\/div>\n<div class=\"card bg-green\">\n<h3>11) Embedding vs Referencing<\/h3>\n<p>Embed when data is accessed together and bounded in size (product + reviews snapshot). Reference when many-to-many, unbounded growth, or reuse across documents. Optimize for read patterns.<\/p>\n<pre><code class=\"mono\">\/\/ Embed example\r\n{ _id:1, name:\"Post\", comments:[{ by:\"u1\", text:\"hi\" }] }<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-blue\">\n<h3>12) Schema Design Rule<\/h3>\n<p>\u201cData that is accessed together should be stored together.\u201d Model queries first. Precompute aggregates if needed. Avoid \u201c3rd NF\u201d mindset\u2014join costs can be high.<\/p>\n<pre><code class=\"mono\">\/\/ Orders keep buyer snapshot to avoid cross-collection joins<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-amber\">\n<h3>13) Document Growth &#038; Padding<\/h3>\n<p>Growing documents may trigger move\/rewrite. Avoid unbounded arrays; use bucketing (e.g., monthly activity docs) or <code>$push<\/code> with <code>$slice<\/code>.<\/p>\n<pre><code class=\"mono\">db.posts.updateOne({_id:1}, { $push:{ comments:{ $each:[c], $slice:-100 } } })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-violet\">\n<h3>14) CRUD Examples<\/h3>\n<p>Use operators: <code>$set<\/code>, <code>$inc<\/code>, <code>$push<\/code>, <code>$pull<\/code>, <code>$addToSet<\/code>. Upserts combine insert + update.<\/p>\n<pre><code class=\"mono\">db.users.updateOne({ email }, { $set:{ name }, $inc:{ logins:1 } }, { upsert:true })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-rose\">\n<h3>15) Array Operators<\/h3>\n<p>Use <code>$elemMatch<\/code>, positional <code>$<\/code>\/<code>$[]<\/code> to update matching elements. <code>$size<\/code>, <code>$slice<\/code> for reads. Consider <code>$addToSet<\/code> to avoid duplicates.<\/p>\n<pre><code class=\"mono\">db.c.updateOne({ _id:1, \"tags\":\"js\" }, { $set:{ \"tags.$\":\"javascript\" } })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-cyan\">\n<h3>16) Validation<\/h3>\n<p>JSON Schema validation at collection level ensures shape and ranges. Use <code>validationAction<\/code> warn\/strict.<\/p>\n<pre><code class=\"mono\">db.createCollection(\"users\",{ validator:{ $jsonSchema:{ bsonType:\"object\", required:[\"email\"] }}})<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-lime\">\n<h3>17) Bulk Writes<\/h3>\n<p>Batch operations with <code>bulkWrite<\/code> reduce round-trips and improve throughput. Choose ordered\/unordered by failure semantics.<\/p>\n<pre><code class=\"mono\">db.users.bulkWrite([{ insertOne:{ document:{email:\"a\"}} }, { updateOne:{ filter:{email:\"a\"}, update:{ $set:{name:\"A\"}}}}])<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-orange\">\n<h3>18) Transactions<\/h3>\n<p>Multi-document ACID transactions across a replica set or sharded cluster. Use for truly atomic multi-collection updates; keep them short.<\/p>\n<pre><code class=\"mono\">const s = db.getMongo().startSession(); s.startTransaction();\r\ntry { s.getDatabase(\"shop\").orders.insertOne(o); s.commitTransaction(); } catch(e){ s.abortTransaction(); }<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-indigo\">\n<h3>19) Change Streams<\/h3>\n<p>Subscribe to real-time data changes from the oplog\u2014great for triggers, caching, search indexing. Requires replica set.<\/p>\n<pre><code class=\"mono\">db.collection.watch([{ $match:{ \"operationType\":{ $in:[\"insert\",\"update\"]}} }])<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-slate\">\n<h3>20) Q&amp;A \u2014 \u201cWhen to use transactions?\u201d<\/h3>\n<p><span class=\"q\">Answer:<\/span> When invariants span multiple documents\/collections (e.g., money transfer, inventory + order). Otherwise prefer single-document atomic updates with operators for better performance.<\/p>\n<\/p><\/div>\n<p>      <!-- ===================== SECTION 3: INDEXING, AGGREGATION & SEARCH (21\u201330) ===================== --><\/p>\n<div class=\"section-title\">Section 3 \u2014 Indexing, Aggregation &#038; Search<\/div>\n<div class=\"card bg-green\">\n<h3>21) Compound Indexes<\/h3>\n<p>Index order matters: prefix fields must match query\u2019s sort\/filter. A query on leftmost fields can use the index. Design around your most common <code>$match<\/code> + <code>$sort<\/code>.<\/p>\n<pre><code class=\"mono\">db.orders.createIndex({ userId:1, createdAt:-1 })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-blue\">\n<h3>22) Partial &#038; Sparse Index<\/h3>\n<p><b>Partial<\/b> indexes only include docs matching an expression\u2014smaller\/faster. <b>Sparse<\/b> only index docs where the field exists.<\/p>\n<pre><code class=\"mono\">db.users.createIndex({ \"email\":1 }, { partialFilterExpression:{ verified:true } })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-amber\">\n<h3>23) TTL &#038; Expire<\/h3>\n<p>TTL indexes automatically delete docs after a time-to-live or at a date field. Great for sessions, temp data.<\/p>\n<pre><code class=\"mono\">db.sessions.createIndex({ \"expiresAt\":1 }, { expireAfterSeconds:0 })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-violet\">\n<h3>24) Text &#038; Atlas Search<\/h3>\n<p>Built-in text index supports stemming\/scores; Atlas Search (Lucene-based) offers rich full-text, facets, and relevance tuning (managed in Atlas).<\/p>\n<pre><code class=\"mono\">db.articles.createIndex({ content:\"text\", title:\"text\" })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-rose\">\n<h3>25) Geospatial<\/h3>\n<p>2dsphere indexes for GeoJSON (<code>Point<\/code>, <code>Polygon<\/code>); queries like <code>$near<\/code>, <code>$geoWithin<\/code>. Store coords as [lng, lat].<\/p>\n<pre><code class=\"mono\">db.places.createIndex({ loc:\"2dsphere\" })\r\ndb.places.find({ loc:{ $near:{ $geometry:{ type:\"Point\", coordinates:[-0.1,51.5] }, $maxDistance:5000 }}})<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-cyan\">\n<h3>26) Aggregation Patterns<\/h3>\n<p>Use <code>$match<\/code> early, <code>$project<\/code> to reduce fields, and <code>$group<\/code> for rollups. <code>$lookup<\/code> for joins (beware big fan-out). <code>$facet<\/code> runs multiple pipelines in one pass.<\/p>\n<pre><code class=\"mono\">db.sales.aggregate([\r\n { $match:{ ts:{ $gte:ISODate(\"2025-01-01\") }}},\r\n { $group:{ _id:\"$sku\", qty:{ $sum:\"$qty\" }, rev:{ $sum:\"$amount\" } }},\r\n { $sort:{ rev:-1 } }, { $limit:10 }\r\n])<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-lime\">\n<h3>27) Performance Explain<\/h3>\n<p>Use <code>explain(\"executionStats\")<\/code> to inspect index use, scanned vs returned, stage tree. Fix COLLSCANs, add\/adjust indexes.<\/p>\n<pre><code class=\"mono\">db.orders.find({ userId:1 }).sort({ createdAt:-1 }).explain(\"executionStats\")<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-orange\">\n<h3>28) Aggregation Windows<\/h3>\n<p>Window operators (<code>$setWindowFields<\/code>) compute moving averages, ranks, etc., over partitions\u2014handy for analytics without exporting to Spark.<\/p>\n<pre><code class=\"mono\">db.m.find().aggregate([{ $setWindowFields:{ partitionBy:\"$userId\", sortBy:{ts:1}, output:{ runAvg:{ $avg:\"$v\", window:{ documents:[-5,0] }}}}}])<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-indigo\">\n<h3>29) Faceted Search<\/h3>\n<p>Build search pages with counts per facet using <code>$facet<\/code> to compute buckets in one pipeline, reducing extra round-trips.<\/p>\n<pre><code class=\"mono\">db.products.aggregate([{ $match:{ inStock:true } },{ $facet:{ brands:[{ $sortByCount:\"$brand\"}], price:[{ $bucket:{ groupBy:\"$price\", boundaries:[0,50,100,200,1000] }}] }}])<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-slate\">\n<h3>30) Q&amp;A \u2014 \u201cCompound index order?\u201d<\/h3>\n<p><span class=\"q\">Answer:<\/span> Put equality fields first, then sort\/range fields. The index must support your <code>$sort<\/code> order; otherwise MongoDB sorts in memory. Design around your top N query patterns.<\/p>\n<\/p><\/div>\n<p>      <!-- ===================== SECTION 4: PERFORMANCE, OPS & SECURITY (31\u201340) ===================== --><\/p>\n<div class=\"section-title\">Section 4 \u2014 Performance, Operations &#038; Security<\/div>\n<div class=\"card bg-green\">\n<h3>31) Connection Pooling<\/h3>\n<p>Use driver pools; avoid creating clients per request. Configure timeouts and keep-alive. Monitor connection counts to primary\/secondaries.<\/p>\n<pre><code class=\"mono\">\/\/ Node.js\r\nimport { MongoClient } from \"mongodb\";\r\nconst client = new MongoClient(uri, { maxPoolSize: 50 });<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-blue\">\n<h3>32) Write Patterns<\/h3>\n<p>Use single-document atomic ops. Avoid read-modify-write races by leveraging operators like <code>$inc<\/code> and <code>$currentDate<\/code>. Apply idempotency keys for at-least-once inputs.<\/p>\n<pre><code class=\"mono\">db.counters.updateOne({ _id:\"order\" }, { $inc:{ seq:1 } }, { upsert:true })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-amber\">\n<h3>33) Hot Partitions &#038; Shard Keys<\/h3>\n<p>Avoid monotonically increasing shard keys (e.g., timestamp) that hotspot the last chunk. Use hashed shard keys or compound keys with good distribution and query targeting.<\/p>\n<pre><code class=\"mono\">sh.shardCollection(\"app.events\", { userId:\"hashed\" })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-violet\">\n<h3>34) Backups &#038; PITR<\/h3>\n<p>Use Cloud\/Atlas backups or filesystem snapshots with consistent checkpoints. Oplog-based Point-in-Time Restore (PITR) enables recovering to a timestamp.<\/p>\n<pre><code class=\"mono\"># Atlas: continuous backups + PITR window (UI\/CLI)<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-rose\">\n<h3>35) Monitoring<\/h3>\n<p>Watch Opcounters, page faults, queue lengths, replication lag, WT cache pressure, and slow queries. Enable profiler at low sampling for hotspots.<\/p>\n<pre><code class=\"mono\">db.setProfilingLevel(1, 100) \/\/ log ops slower than 100ms<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-cyan\">\n<h3>36) Security Basics<\/h3>\n<p>Enable auth, enforce TLS, restrict network, use SCRAM users with least privilege, rotate keys. Encrypt at rest; use field-level encryption for PII where needed.<\/p>\n<pre><code class=\"mono\"># mongod.conf\r\nsecurity:\r\n  authorization: enabled<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-lime\">\n<h3>37) Read\/Write Patterns at Scale<\/h3>\n<p>Batch writes, use unordered bulk for higher throughput, set appropriate write concern. For reads, use projections to return only needed fields and indexes that support sort.<\/p>\n<pre><code class=\"mono\">db.users.find({active:true}, { projection:{ email:1, name:1 }})<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-orange\">\n<h3>38) Caching &#038; Secondary Reads<\/h3>\n<p>Cache hot reads at app layer. For replicas, use <code>readPreference: secondary<\/code> for non-critical analytics; understand eventual consistency.<\/p>\n<pre><code class=\"mono\">\/\/ Node.js\r\ncoll.find(q, { readPreference: \"secondaryPreferred\" })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-indigo\">\n<h3>39) Multi-Tenancy<\/h3>\n<p>Per-tenant databases\/collections or a shared collection with <code>tenantId<\/code> in the shard key and unique index partials. Enforce via app and (in Atlas) data access controls.<\/p>\n<pre><code class=\"mono\">db.items.createIndex({ tenantId:1, key:1 }, { unique:true, partialFilterExpression:{ tenantId:{ $exists:true }}})<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-slate\">\n<h3>40) Q&amp;A \u2014 \u201cWhy is my query slow?\u201d<\/h3>\n<p><span class=\"q\">Answer:<\/span> Missing\/inefficient indexes, low selectivity, in-memory sort, large projections, or sharding causing scatter-gather. Fix with targeted compound indexes, projections, and query routing to the correct shard.<\/p>\n<\/p><\/div>\n<p>      <!-- ===================== SECTION 5: RECIPES, PITFALLS & INTERVIEW Q&A (41\u201350) ===================== --><\/p>\n<div class=\"section-title\">Section 5 \u2014 Recipes, Pitfalls &#038; Interview Q&amp;A<\/div>\n<div class=\"card bg-green\">\n<h3>41) Pagination<\/h3>\n<p>Prefer range-based (bookmark) pagination over <code>skip\/limit<\/code> for large offsets. Use an indexed field (e.g., <code>_id<\/code> or <code>createdAt<\/code>).<\/p>\n<pre><code class=\"mono\">db.posts.find({ _id:{ $gt:lastId } }).sort({ _id:1 }).limit(20)<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-blue\">\n<h3>42) Unique Constraints<\/h3>\n<p>Enforce uniqueness with unique indexes; for scoped uniqueness use compound or partial unique indexes.<\/p>\n<pre><code class=\"mono\">db.users.createIndex({ tenantId:1, email:1 }, { unique:true })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-amber\">\n<h3>43) Upsert Idempotency<\/h3>\n<p>Design idempotent upserts using natural keys and <code>$setOnInsert<\/code>. Prevent duplicates in retries.<\/p>\n<pre><code class=\"mono\">db.payments.updateOne({ extId }, { $set:{status:\"paid\"}, $setOnInsert:{ createdAt:new Date() } }, { upsert:true })<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-violet\">\n<h3>44) Soft Deletes<\/h3>\n<p>Use <code>deletedAt<\/code> timestamps and partial indexes that ignore deleted docs, or move to an archive collection.<\/p>\n<pre><code class=\"mono\">db.items.createIndex({ email:1 }, { unique:true, partialFilterExpression:{ deletedAt:{ $exists:false }}})<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-rose\">\n<h3>45) Pre-Aggregations<\/h3>\n<p>Materialize aggregates (daily rollups) into separate collections via scheduled jobs\/change streams to speed dashboards.<\/p>\n<pre><code class=\"mono\">\/\/ write to reports.daily_sales { day, sku, qty, rev }<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-cyan\">\n<h3>46) Time-Series Collections<\/h3>\n<p>Use time-series collections for telemetry: automatic bucketing, compressed storage, and optimized queries on time\/metadata.<\/p>\n<pre><code class=\"mono\">db.createCollection(\"metrics\",{ timeseries:{ timeField:\"ts\", metaField:\"host\", granularity:\"minutes\" }})<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-lime\">\n<h3>47) Large Files (GridFS)<\/h3>\n<p>For files &gt;16MB, use GridFS to chunk and store; otherwise prefer object storage (S3) and keep only metadata\/URLs in MongoDB.<\/p>\n<pre><code class=\"mono\"># GridFS via drivers (fs.files, fs.chunks)<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-orange\">\n<h3>48) Common Pitfalls<\/h3>\n<p>Designing schemas like SQL, unbounded arrays, skip\/limit deep pages, scatter-gather queries, monotonous shard keys, and missing TTLs for ephemeral data.<\/p>\n<pre><code class=\"mono\">\/\/ Fix with embedding, bucketing, range pagination, hashed\/compound shard keys<\/code><\/pre>\n<\/p><\/div>\n<div class=\"card bg-indigo\">\n<h3>49) Mini Checklist<\/h3>\n<p class=\"tight\">\n<ul>\n<li>Model around queries &#038; workloads<\/li>\n<li>Compound indexes support filter+sort<\/li>\n<li>Use projections, avoid large docs<\/li>\n<li>Backups + PITR tested<\/li>\n<li>Auth\/TLS + least privilege<\/li>\n<\/ul>\n<\/p><\/div>\n<div class=\"card bg-slate qa\">\n<h3>50) Interview Q&amp;A \u2014 20 Practical Questions (Expanded)<\/h3>\n<p><b>1)<\/b> <span class=\"q\">Embedding vs referencing?<\/span> Embed when data is accessed together and bounded; reference for many-to-many\/unbounded or shared entities.<\/p>\n<p><b>2)<\/b> <span class=\"q\">How to pick a shard key?<\/span> High cardinality, even write distribution, and query targeting. Avoid hotspots; consider hashed or compound keys.<\/p>\n<p><b>3)<\/b> <span class=\"q\">Write concern vs read concern?<\/span> Write concern = durability guarantees; read concern = consistency level. Tune per op\/txn.<\/p>\n<p><b>4)<\/b> <span class=\"q\">When use transactions?<\/span> Only when invariants span multiple documents\/collections; keep txns short to avoid lock contention.<\/p>\n<p><b>5)<\/b> <span class=\"q\">Indexes for sort + filter?<\/span> Compound with equality fields first, then sort\/range fields, matching sort order.<\/p>\n<p><b>6)<\/b> <span class=\"q\">Avoid skip\/limit?<\/span> Use range pagination with indexed fields; <code>skip<\/code> scans O(n).<\/p>\n<p><b>7)<\/b> <span class=\"q\">Handle schema changes?<\/span> Use schema versioning and migration scripts; keep validators lenient during rollout.<\/p>\n<p><b>8)<\/b> <span class=\"q\">Why COLLSCAN?<\/span> No matching index, low selectivity, or expression not supported by index. Add\/rewrite index or reshape query.<\/p>\n<p><b>9)<\/b> <span class=\"q\">Partial index use?<\/span> Smaller, faster indexes when you only query a subset (e.g., <code>active:true<\/code>).<\/p>\n<p><b>10)<\/b> <span class=\"q\">Change streams use cases?<\/span> Cache invalidation, search indexing, CDC to warehouses, reactive systems.<\/p>\n<p><b>11)<\/b> <span class=\"q\">Atlas Search vs text index?<\/span> Atlas Search offers Lucene features, scoring, facets, and better relevance; text index is basic.<\/p>\n<p><b>12)<\/b> <span class=\"q\">Time-series benefits?<\/span> Compressed storage, automatic bucketing, faster time-bounded queries.<\/p>\n<p><b>13)<\/b> <span class=\"q\">Monotonic shard key problem?<\/span> Hot chunk receives all new writes; fix with hashed or compound shard keys.<\/p>\n<p><b>14)<\/b> <span class=\"q\">Ensure idempotency?<\/span> Natural keys + <code>$setOnInsert<\/code>, dedupe tokens, and unique indexes.<\/p>\n<p><b>15)<\/b> <span class=\"q\">Geospatial basics?<\/span> 2dsphere index, GeoJSON types, queries like <code>$near<\/code>\/<code>$geoWithin<\/code>.<\/p>\n<p><b>16)<\/b> <span class=\"q\">Profiler usage?<\/span> Capture slow ops to tune indexes and queries; don\u2019t leave at level 2 in prod.<\/p>\n<p><b>17)<\/b> <span class=\"q\">Field-level encryption?<\/span> Encrypt sensitive fields client-side; server stores ciphertext; keys via KMS.<\/p>\n<p><b>18)<\/b> <span class=\"q\">Bulk vs single writes?<\/span> Bulk reduces round-trips and improves throughput; unordered is fastest but partial failures need handling.<\/p>\n<p><b>19)<\/b> <span class=\"q\">Aggregation optimization?<\/span> <code>$match<\/code> early, projections, index-friendly operators, avoid unwinds on huge arrays without filters.<\/p>\n<p><b>20)<\/b> <span class=\"q\">Replica set lag?<\/span> Network\/IO pressure; tune write concern, optimize secondaries, and monitor oplog window.<\/p>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>MongoDB Pocket Book \u2014 Uplatz 50 in-depth cards \u2022 Wide layout \u2022 Readable examples \u2022 20-Q interview block included Section 1 \u2014 Foundations 1) What is MongoDB? MongoDB is a <span class=\"readmore\"><a href=\"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/\">Read More &#8230;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2468,2462],"tags":[],"class_list":["post-4438","post","type-post","status-publish","format-standard","hentry","category-mongodb","category-pocket-book"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MongoDB Pocket Book | Uplatz Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MongoDB Pocket Book | Uplatz Blog\" \/>\n<meta property=\"og:description\" content=\"MongoDB Pocket Book \u2014 Uplatz 50 in-depth cards \u2022 Wide layout \u2022 Readable examples \u2022 20-Q interview block included Section 1 \u2014 Foundations 1) What is MongoDB? MongoDB is a Read More ...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/\" \/>\n<meta property=\"og:site_name\" content=\"Uplatz Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Uplatz-1077816825610769\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-09T13:52:57+00:00\" \/>\n<meta name=\"author\" content=\"uplatzblog\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@uplatz_global\" \/>\n<meta name=\"twitter:site\" content=\"@uplatz_global\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"uplatzblog\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/\"},\"author\":{\"name\":\"uplatzblog\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#\\\/schema\\\/person\\\/8ecae69a21d0757bdb2f776e67d2645e\"},\"headline\":\"MongoDB Pocket Book\",\"datePublished\":\"2025-08-09T13:52:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/\"},\"wordCount\":1421,\"publisher\":{\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#organization\"},\"articleSection\":[\"MongoDB\",\"Pocket Book\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/\",\"url\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/\",\"name\":\"MongoDB Pocket Book | Uplatz Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#website\"},\"datePublished\":\"2025-08-09T13:52:57+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/mongodb-pocket-book\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MongoDB Pocket Book\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/\",\"name\":\"Uplatz Blog\",\"description\":\"Uplatz is a global IT Training &amp; Consulting company\",\"publisher\":{\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#organization\",\"name\":\"uplatz.com\",\"url\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/11\\\/Uplatz-Logo-Copy-2.png\",\"contentUrl\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/11\\\/Uplatz-Logo-Copy-2.png\",\"width\":1280,\"height\":800,\"caption\":\"uplatz.com\"},\"image\":{\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Uplatz-1077816825610769\\\/\",\"https:\\\/\\\/x.com\\\/uplatz_global\",\"https:\\\/\\\/www.instagram.com\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/7956715?trk=tyah&amp;amp;amp;amp;trkInfo=clickedVertical:company,clickedEntityId:7956715,idx:1-1-1,tarId:1464353969447,tas:uplatz\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/uplatz.com\\\/blog\\\/#\\\/schema\\\/person\\\/8ecae69a21d0757bdb2f776e67d2645e\",\"name\":\"uplatzblog\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7f814c72279199f59ded4418a8653ad15f5f8904ac75e025a4e2abe24d58fa5d?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7f814c72279199f59ded4418a8653ad15f5f8904ac75e025a4e2abe24d58fa5d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7f814c72279199f59ded4418a8653ad15f5f8904ac75e025a4e2abe24d58fa5d?s=96&d=mm&r=g\",\"caption\":\"uplatzblog\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MongoDB Pocket Book | Uplatz Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/","og_locale":"en_US","og_type":"article","og_title":"MongoDB Pocket Book | Uplatz Blog","og_description":"MongoDB Pocket Book \u2014 Uplatz 50 in-depth cards \u2022 Wide layout \u2022 Readable examples \u2022 20-Q interview block included Section 1 \u2014 Foundations 1) What is MongoDB? MongoDB is a Read More ...","og_url":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/","og_site_name":"Uplatz Blog","article_publisher":"https:\/\/www.facebook.com\/Uplatz-1077816825610769\/","article_published_time":"2025-08-09T13:52:57+00:00","author":"uplatzblog","twitter_card":"summary_large_image","twitter_creator":"@uplatz_global","twitter_site":"@uplatz_global","twitter_misc":{"Written by":"uplatzblog"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/#article","isPartOf":{"@id":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/"},"author":{"name":"uplatzblog","@id":"https:\/\/uplatz.com\/blog\/#\/schema\/person\/8ecae69a21d0757bdb2f776e67d2645e"},"headline":"MongoDB Pocket Book","datePublished":"2025-08-09T13:52:57+00:00","mainEntityOfPage":{"@id":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/"},"wordCount":1421,"publisher":{"@id":"https:\/\/uplatz.com\/blog\/#organization"},"articleSection":["MongoDB","Pocket Book"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/","url":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/","name":"MongoDB Pocket Book | Uplatz Blog","isPartOf":{"@id":"https:\/\/uplatz.com\/blog\/#website"},"datePublished":"2025-08-09T13:52:57+00:00","breadcrumb":{"@id":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/uplatz.com\/blog\/mongodb-pocket-book\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/uplatz.com\/blog\/"},{"@type":"ListItem","position":2,"name":"MongoDB Pocket Book"}]},{"@type":"WebSite","@id":"https:\/\/uplatz.com\/blog\/#website","url":"https:\/\/uplatz.com\/blog\/","name":"Uplatz Blog","description":"Uplatz is a global IT Training &amp; Consulting company","publisher":{"@id":"https:\/\/uplatz.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/uplatz.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/uplatz.com\/blog\/#organization","name":"uplatz.com","url":"https:\/\/uplatz.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/uplatz.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/uplatz.com\/blog\/wp-content\/uploads\/2016\/11\/Uplatz-Logo-Copy-2.png","contentUrl":"https:\/\/uplatz.com\/blog\/wp-content\/uploads\/2016\/11\/Uplatz-Logo-Copy-2.png","width":1280,"height":800,"caption":"uplatz.com"},"image":{"@id":"https:\/\/uplatz.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Uplatz-1077816825610769\/","https:\/\/x.com\/uplatz_global","https:\/\/www.instagram.com\/","https:\/\/www.linkedin.com\/company\/7956715?trk=tyah&amp;amp;amp;amp;trkInfo=clickedVertical:company,clickedEntityId:7956715,idx:1-1-1,tarId:1464353969447,tas:uplatz"]},{"@type":"Person","@id":"https:\/\/uplatz.com\/blog\/#\/schema\/person\/8ecae69a21d0757bdb2f776e67d2645e","name":"uplatzblog","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/7f814c72279199f59ded4418a8653ad15f5f8904ac75e025a4e2abe24d58fa5d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/7f814c72279199f59ded4418a8653ad15f5f8904ac75e025a4e2abe24d58fa5d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7f814c72279199f59ded4418a8653ad15f5f8904ac75e025a4e2abe24d58fa5d?s=96&d=mm&r=g","caption":"uplatzblog"}}]}},"_links":{"self":[{"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/posts\/4438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/comments?post=4438"}],"version-history":[{"count":1,"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/posts\/4438\/revisions"}],"predecessor-version":[{"id":4439,"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/posts\/4438\/revisions\/4439"}],"wp:attachment":[{"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/media?parent=4438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/categories?post=4438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/uplatz.com\/blog\/wp-json\/wp\/v2\/tags?post=4438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}