Module: MongoDB
MongoDB·146·8 MIN READ

146: Advanced MongoDB Features — Change Streams, Time Series, GridFS, Geospatial, Search, Vector Search, and Specialized Workloads

TOPICS COVERED: Advanced MongoDB Features — Change Streams, Time Series, GridFS, Geospatial, Search, Vector Search, and Specialized Workloads

Learning objectives

You will learn to:

  • choose specialized MongoDB features based on workload;
  • design reliable change-stream consumers;
  • understand time-series collections;
  • understand GridFS and when not to use it;
  • model geospatial data and queries;
  • distinguish classic text indexes from MongoDB Search;
  • understand MongoDB Vector Search;
  • understand hybrid search at a practical level;
  • understand specialized feature limitations;
  • avoid forcing every data problem into one MongoDB feature.

Why specialized features come late

You first learned:

text
documents
modeling
CRUD
indexes
aggregation
transactions
replication
sharding
security
operations
driver

Now you can evaluate specialized features without treating them as magic.

Change streams recap

Change streams let an application subscribe to MongoDB changes on:

  • collection;
  • database;
  • deployment.

They are available on replica sets and sharded clusters.

Example:

js
const stream = db
  .collection('orders')
  .watch([
    {
      $match: {
        operationType: {
          $in: [
            'insert',
            'update',
          ],
        },
      },
    },
  ]);

Consume:

js
for await (const change of stream) {
  await handleChange(change);
}

Change event shape

Can include fields such as:

text
_id                 resume token
operationType
clusterTime
ns
documentKey
updateDescription
fullDocument
fullDocumentBeforeChange

depending operation/options/configuration.

Do not assume full document always present.

Full document lookup

For updates, request post-change document with supported option such as:

text
fullDocument: "updateLookup"

This performs lookup and can add load.

If you only need changed field names, use updateDescription.

Pre/post images

MongoDB can store pre/post images for configured collections.

Useful for:

  • audit;
  • diff;
  • event processors requiring old/new.

Costs:

  • storage;
  • privileges;
  • retention;
  • operational complexity.

Do not enable globally without need.

Resume

Store resume token after successfully applying event:

text
receive
↓
process idempotently
↓
persist output/state
↓
persist resume token

If you persist token before completing side effect, crash can skip unfinished event.

If you persist token after non-idempotent side effect, crash can repeat side effect.

Therefore consumers should be idempotent.

Change stream and exactly-once myth

A change stream alone does not automatically produce exactly-once external side effects.

For:

text
send email
charge card
publish webhook

use:

  • idempotency keys;
  • durable processed-event record;
  • outbox;
  • transactional projection design.

Rebuildable projection

A robust read model consumer should ideally support:

text
rebuild from source
+
resume live changes

If resume history expires, you can rebuild.

Do not make one forgotten resume token the only way to reconstruct critical data.

Time-series data

Workloads:

  • sensors;
  • metrics;
  • IoT;
  • telemetry;
  • measurements.

Time-series collection groups data by:

text
time field
meta field
granularity/bucketing

Example:

javascript
db.createCollection(
  "deviceMetrics",
  {
    timeseries: {
      timeField: "timestamp",
      metaField: "device",
      granularity: "seconds"
    }
  }
)

Document:

javascript
{
  timestamp: new Date(),
  device: {
    tenantId,
    deviceId,
    region: "south"
  },
  temperature: 28.4,
  humidity: 63
}

Time-series meta field

Put stable metadata used to group/filter:

text
device ID
sensor type
tenant
site

Avoid frequently changing high-cardinality metadata structure that defeats efficient bucketing.

Design from query patterns.

Time-series limitations

Time-series collections have specific limitations.

As of current MongoDB documentation:

  • change streams are not supported on time-series collections;
  • MongoDB Search/Vector Search is not supported for time-series collections in the ordinary way;
  • some schema/collection operations have restrictions.

Check current version before choosing.

Do not assume a normal collection feature automatically works on time series.

Time-series retention

Use expireAfterSeconds for automatic data expiration where appropriate.

TTL cleanup is asynchronous.

For regulatory/analytics retention, design archival before expiry.

Downsampling

High-frequency telemetry can be expensive long-term.

Architecture:

text
raw 1-second metrics retained 7 days
5-minute aggregates retained 1 year

Use aggregation/materialized summaries/Atlas features according to needs.

GridFS

MongoDB GridFS stores large files by splitting them into chunks plus metadata.

Collections conceptually:

text
fs.files
fs.chunks

Use when:

  • files need MongoDB-managed storage semantics;
  • files exceed document size;
  • operational architecture favors DB-backed file storage.

When object storage is better

For:

  • photos;
  • videos;
  • PDFs;
  • public assets;
  • large downloads;

S3-compatible/object storage + CDN is often better:

  • cheaper;
  • scalable;
  • range requests/CDN;
  • lifecycle policies;
  • specialized durability.

GridFS is not automatically the right choice because app already uses MongoDB.

GridFS Node driver

Driver exposes GridFSBucket.

Concept:

js
const bucket = new GridFSBucket(db);

await pipeline(
  fileInput,
  bucket.openUploadStream(
    safeFilename,
    {
      metadata: {
        tenantId,
      },
    },
  ),
);

Download:

js
await pipeline(
  bucket.openDownloadStream(fileId),
  httpResponse,
);

Use streaming/backpressure.

GridFS security

Do not trust original filename for authorization.

Metadata:

text
tenantId
ownerId
contentType
size
hash/scanning status

Application query should scope file ID + tenant.

Uploaded file policy remains:

  • size limit;
  • MIME/signature;
  • malware;
  • content-disposition;
  • safe serving.

Geospatial model

GeoJSON Point:

javascript
{
  location: {
    type: "Point",
    coordinates: [
      78.1198,
      9.9252
    ]
  }
}

Coordinates are:

text
longitude
latitude

Index:

javascript
db.places.createIndex({
  location: "2dsphere"
})

$near

Find nearest places:

javascript
db.places.find({
  location: {
    $near: {
      $geometry: {
        type: "Point",
        coordinates: [
          78.12,
          9.92
        ]
      },
      $maxDistance: 5000
    }
  }
})

Use index.

Distance units depend on operator.

Check docs.

$geoWithin

Find points inside polygon/shape.

Useful for:

  • service area;
  • delivery zone;
  • geofencing.

Geospatial boundary precision and coordinate reference assumptions matter.

Do not implement legal/cadastral precision blindly with general GeoJSON.

$geoNear

Aggregation stage can calculate distance and enrich output.

Must follow stage/index rules.

Useful:

text
nearest stores
then lookup inventory
then filter availability

But query may become expensive.

Classic MongoDB text index supports basic search.

javascript
db.articles.createIndex({
  title: "text",
  body: "text"
})

Query:

javascript
{
  $text: {
    $search: "mongodb indexing"
  }
}

Useful for simple workloads.

Limited compared with MongoDB Search.

MongoDB Search provides Lucene-based search capabilities in supported deployments/products.

Capabilities include:

  • relevance;
  • analyzers;
  • autocomplete;
  • fuzzy matching;
  • facets;
  • compound search;
  • highlighting.

Search indexes are managed separately from normal MongoDB indexes.

Pipeline uses:

text
$search
$searchMeta

Do not use createIndex() and expect Atlas Search behavior.

Search index mapping

Define fields/analyzers deliberately.

Dynamic mapping is easy for prototypes but can index more fields than needed.

Production:

  • explicit searchable fields;
  • analyzers/language;
  • stored source choices;
  • autocomplete;
  • synonyms where appropriate.

Search indexing consumes storage/resources.

Autocomplete

A prefix-like UX should not use:

javascript
{
  name: {
    $regex: userInput,
  }
}

over millions of documents.

Search autocomplete index/operator can provide better scalable relevance behavior.

Search security

Search results must still enforce tenant/access scope.

Include tenant filter in search pipeline using supported compound filters or architecture.

Do not search global index then filter unauthorized results only after returning too many.

Authorization belongs before/exactly within data query.

Vector search finds semantically similar vectors.

Typical flow:

text
text/image/document
↓
embedding model
↓
vector array
↓
vector index
↓
nearest-neighbor query

Document:

javascript
{
  tenantId,
  content: "...",
  embedding: [
    0.013,
    -0.22,
    ...
  ]
}

Vector index

MongoDB's vector search uses a specialized vector index in supported deployment.

Query uses $vectorSearch stage.

Concept:

javascript
{
  $vectorSearch: {
    index: "content_vector",
    path: "embedding",
    queryVector: [...],
    numCandidates: 200,
    limit: 10,
    filter: {
      tenantId: tenantId
    }
  }
}

Exact supported filters/options depend on current MongoDB version/service.

Do not copy dimensions/index settings from another embedding model.

Embedding dimensions

Vector size must match index/model.

If model changes:

text
1536 dimensions
→ 3072 dimensions

existing index/data may require migration/new field/index.

Version embeddings:

javascript
{
  embeddingModel: "model-x-v2",
  embedding: [...]
}

Similarity function

Vector indexes support similarity metrics such as cosine/dot/euclidean depending service/config.

Match embedding model recommendation.

Do not choose metric by intuition.

Combine:

text
lexical relevance
+
semantic/vector relevance

Useful when exact terms matter and semantic similarity helps.

Example:

text
"Node 26 memory leak"

Lexical exact version term plus semantic meaning.

Hybrid ranking architecture may use reciprocal-rank fusion or product-specific scoring.

Use MongoDB's current Search/Vector capabilities rather than manually merging huge result sets when platform provides suitable feature.

Retrieval-Augmented Generation (RAG)

Vector search can retrieve context for LLM.

Security rules:

  1. filter tenant/permissions during retrieval;
  2. never rely on model to hide unauthorized text;
  3. treat retrieved documents as untrusted content;
  4. apply prompt-injection defenses;
  5. log carefully;
  6. include source references where product requires.

Database authorization comes before generation.

Vector data cost

Embeddings consume storage and indexing memory.

Millions of high-dimensional vectors can be significant.

Measure:

  • index size;
  • query latency;
  • ingestion rate;
  • model embedding cost;
  • reindex cost.

Do not add vector field to every document without product need.

Search consistency

Search indexes may have synchronization delay relative to database writes.

Do not use Search index for a strongly consistent authorization or financial existence check.

Use ordinary Mongo query for authoritative state.

Search is retrieval system.

Search pagination

Search supports specialized pagination mechanisms.

Do not use deep $skip through relevance results.

Use search-after/search-before style APIs where supported.

Specialized workload decision table

NeedFeature
realtime DB changesChange Streams
sensor telemetryTime Series
DB-managed large binaryGridFS
nearest location2dsphere
full-text/autocompleteMongoDB Search
semantic similarityVector Search
strict transactional truthordinary collection + transactions/atomic writes

Do not solve every problem with aggregation.

Failure clinic

Time-series + change stream assumed supported

Wrong feature combination.

GridFS for public images without considering object storage/CDN

Cost/performance mismatch.

geo coordinates reversed

Wrong locations.

regex used as search engine

Slow/poor relevance.

vector query lacks tenant filter

Security breach.

search result treated as authoritative latest state

Index lag problem.

embedding model changed without migration version

Index incompatibility.

change-stream token stored before side effect

Potential lost event.

Exercises

  1. Build change-stream projection with idempotency.
  2. Persist resume token after durable processing.
  3. Create time-series collection for device readings.
  4. Design raw/downsampled retention.
  5. Stream a file into GridFS and compare with object-storage design.
  6. Build 2dsphere nearest-place query.
  7. Design MongoDB Search index for product name/description/autocomplete.
  8. Design vector document with tenant filter.
  9. Plan embedding-model migration.
  10. Threat-model a RAG search endpoint.
  11. Explain which specialized features cannot be combined on time-series collections.

Mastery checklist

Explain:

  • change stream resume/idempotency;
  • time-series model/limits;
  • GridFS/object storage trade-off;
  • geospatial indexes;
  • classic text versus Search;
  • Search indexes;
  • Vector Search;
  • hybrid/RAG security;
  • search consistency;
  • specialized feature selection.

Official references


Additional specialized-feature depth: lifecycle and architecture boundaries

Specialized indexes and streaming features introduce their own lifecycle.

Search/vector index lifecycle

You need:

text
create index
initial build
monitor sync
deploy query
change mapping/model
rebuild new index
switch traffic
remove old

Do not edit a production index/model and hope every query remains compatible.

For major search changes, version index name:

text
products_search_v1
products_search_v2

Build v2, validate, then switch.

Embedding lifecycle

Vector data is derived.

Store enough metadata to reproduce:

javascript
{
  embedding: [...],
  embeddingModel:
    "model-2026-08",
  embeddedAt:
    new Date(),
  sourceHash:
    "sha256..."
}

When source changes, embedding becomes stale.

Background worker detects/recomputes.

Do not recalculate embedding synchronously on every read.

Vector filtering before retrieval

Permission filter must be supported by vector index/filter fields.

If user only allowed project P1:

text
filter projectId=P1
inside vector search

not:

text
retrieve top 10 global
remove unauthorized

Otherwise:

  • may return zero useful results;
  • can leak timing/metadata;
  • violates least exposure.

Change-stream scaling

One change stream per request/client is expensive.

Instead:

text
one/few backend consumers
→ internal pubsub
→ WebSocket/SSE clients

for many users.

At multi-instance scale, pubsub may need Redis/NATS/Kafka/etc.

Do not open 100k Mongo change streams because 100k browser clients connected.

Change-stream partition/order

Ordering is defined by change stream/topology semantics, but consumers should not invent total business order across unrelated entities if not required.

For per-aggregate workflow, use:

text
version
sequence
event timestamp

and idempotency.

GridFS range downloads

Large media clients may request byte ranges.

GridFS stream APIs are not automatically CDN-grade media serving.

Object storage/CDN handles:

  • range;
  • caching;
  • edge;
  • signed URLs better for many media workloads.

Time-series meta cardinality

If meta field unique for every measurement:

javascript
meta:
{
  requestId:
    randomUUID()
}

bucketing cannot group effectively.

Meta should represent stable series identity.

Geospatial + tenant

Compound geospatial index patterns have restrictions/order considerations.

For multi-tenant places, design query/index according to current Mongo geospatial compound-index rules.

Do not omit tenant security just because $near query syntax is specialized.

Search index lag UX

After product updated:

text
normal Mongo detail shows new title
search may show old title briefly

UI may:

  • accept eventual search;
  • invalidate/local update;
  • show authoritative detail on click.

Document consistency.

Additional exercises

  1. Version a Search index and plan zero-downtime switch.
  2. Design embedding refresh worker using source hash.
  3. Ensure vector filter contains tenant/project.
  4. Replace one-change-stream-per-client with backend fanout architecture.
  5. Compare GridFS versus object storage for video.
  6. Fix high-cardinality time-series meta design.
  7. Design UX for search-index lag.

Production mastery check

Specialized Mongo features should be treated as subsystems with indexing, consistency, scaling, and recovery behavior, not one-line query operators.