Skip to main content
MongoDB CDC ingestion lets a StarTree Pinot realtime table consume MongoDB Change Streams directly, without first copying changes through Kafka, Kinesis, Pulsar, or another durable stream.
This connector is intended for advanced realtime ingestion designs where the MongoDB source namespaces, partitioning, credentials, and replay window are explicitly managed. If you only need to consume Debezium-formatted MongoDB events from Kafka, use the Debezium decoder instead.

How It Works

The connector maps each configured MongoDB source partition to one Pinot partition group:
Use the StarTree MongoDB CDC consumer factory:
Pinot controllers resolve source-partition metadata and checkpoints. Pinot servers open and resume MongoDB Change Stream cursors for the partitions they own. Pinot replication creates another cursor per partition replica, so plan source-side Change Stream load as:
For sharded MongoDB deployments, a cursor opened through mongos can fan out to every shard. Plan closer to:

Source-Partition Contract

MongoDB Change Streams do not expose Kafka-style durable partitions. The connector therefore requires a manifest of physical, disjoint MongoDB namespaces. Follow these rules:
  • Partition IDs are dense, stable integers: 0, 1, 2, and so on.
  • Every descriptor has a globally unique and immutable sourceId, such as atlas-prod-a/app/orders-00.
  • _id values must be globally unique across the configured namespaces.
  • Every insert, update, replace, and delete for one primary key must stay in the same source partition for that key’s lifetime.
  • Do not remove, renumber, rebind, or repartition an active source partition. Create a new Pinot table, snapshot/backfill, catch up CDC, and cut over queries instead.
  • Do not use hash(_id) % currentPartitionCount for upstream routing. Increasing the partition count would move existing keys and break upsert partition affinity.
A common routing pattern is to encode the source partition into the immutable _id:
New partitions can receive only newly created IDs. Existing IDs must continue to route to their original namespace.

Prerequisites

  • MongoDB Atlas, a replica set, or a sharded cluster. Standalone mongod processes do not support Change Streams.
  • MongoDB credentials available to Pinot controllers and servers.
  • find and changeStream permissions on every source namespace.
  • If you use registry mode, find on the manifest collection and listCollections on source databases.
  • If you use outputMode=full_document, MongoDB Server 6.0 or later with Change Stream pre/post-images enabled.
  • An oplog and post-image retention window longer than the maximum Pinot outage and recovery window.

Static Manifest Mode

Use static mode when the source partition list is fixed. Omit partitionDiscoveryMode and set sourcePartitions to a JSON array encoded as a string.
In this mode, every descriptor requires:

Registry Manifest Mode

Use partitionDiscoveryMode=mongodb_manifest when an upstream routing service can append new physical bucket collections. The table config allowlists connection references and points Pinot at one authoritative registry document.
Example registry document:
Registry mode fails closed if an existing descriptor changes, a partition is removed, a partition ID is skipped, a namespace UUID changes, or a later generation mutates an old prefix. maxPartitionCount is a safety limit that prevents a malformed registry from creating unbounded Pinot segments or MongoDB cursors.

Output Modes

For full_document, enable post-images on every source collection:
Source documents must not contain connector-reserved fields such as:

Current-State Upsert Example

Schema:
Realtime upsert config:
comparisonColumns uses the connector-generated comparison value so MongoDB event order is preserved. strictReplicaGroup is required so a query sees a consistent upsert view for each partition.

Capturing Initial Offsets

When creating a table with auto.offset.reset=largest, the controller captures a starting boundary for each partition that does not already provide initialOffset. To include historical documents:
  1. Capture an exact resume boundary for each MongoDB namespace.
  2. Snapshot/backfill the historical data up to that boundary.
  3. Configure each descriptor with the captured initialOffset.
  4. Start realtime CDC consumption from those offsets.
Descriptor example:
Do not substitute a bare clusterTime; the offset must include the resume token and its safe logical time.

Adding Capacity

To append a partition safely:
  1. Create a new, quiescent physical namespace.
  2. Capture the namespace UUID and exact initial offset.
  3. Append only the next highest dense partitionId.
  4. Wait until Pinot reports the new partition group consuming on the required replicas.
  5. Route only new keys to the new namespace.
Do not configure a primary-key segmentPartitionConfig on a table whose MongoDB source-partition count can grow. A growing partition count changes key ownership for older rows.

Troubleshooting