Migrate Into MongoDB — as Real Documents
Everyone migrates to PostgreSQL. Going relational → MongoDB is the harder, under-served direction — and doing it right means real document modelling: typed values, indexes from your keys, and foreign keys folded into embedded arrays. Not tables dumped as flat collections.
How It Works
Connect
Point DBMigrateAIPro at your Oracle or PostgreSQL source and your MongoDB target. It reads the full relational schema — tables, columns, types, primary keys, unique constraints, indexes and foreign keys — with no manual inventory.
Load as typed documents
Each table becomes a collection and each row a typed BSON document. Numbers stay numbers (NUMBER(p,s) → Decimal128, exact), dates become datetimes, booleans stay booleans, BLOBs become Binary, NULLs become null — no stringifying everything through CSV.
Build indexes + verify
Primary keys and unique constraints become unique MongoDB indexes; secondary indexes carry over. Every collection is then count-validated against the source so a rejected document (e.g. a >16MB BSON row) is surfaced, never silently dropped.
Embed related tables (optional)
Turn on 1:N embedding and DBMigrateAIPro folds leaf child tables into their parent as nested arrays — auto-detected from foreign keys. The idiomatic document shape, without hand-writing an aggregation pipeline.
Flat Collections vs Embedded Documents
A customers table and its orders can migrate as two disconnected collections — or as one document shaped for how MongoDB actually reads.
// customers
{ "_id": 1, "name": "Ann" }
// orders (separate collection)
{ "_id": 10, "customer_id": 1, "total": 50.00 }
{ "_id": 11, "customer_id": 1, "total": 70.00 }
// every read is a manual $lookup join// customers (orders folded in as an array)
{
"_id": 1,
"name": "Ann",
"orders": [
{ "_id": 10, "total": { "$numberDecimal": "50.00" } },
{ "_id": 11, "total": { "$numberDecimal": "70.00" } }
]
}Auto-detected from the foreign key. Leaf child → embedded array · junction / referenced tables stay standalone · totals preserved as exact Decimal128.
What Gets Modelled
Structure
- ✓Table → collection
- ✓Row → typed BSON document
- ✓Primary key → unique index
- ✓Unique constraint → unique index
- ✓Secondary indexes → carried over
- ✓Foreign key (1:N) → embedded array (optional)
Type fidelity
- ✓NUMBER(p,s) → Decimal128 (exact — money never becomes a lossy float)
- ✓DATE / TIMESTAMP → BSON datetime
- ✓NUMBER / INTEGER → int / long
- ✓VARCHAR / CLOB / NCLOB → string
- ✓BLOB / RAW → BSON Binary
- ✓BOOLEAN → bool
- ✓NULL → null (not the string "null")
Common Gotchas
These are the issues that quietly wreck relational → document migrations. DBMigrateAIPro handles every one of them.
A naive migration copies each table to a collection and calls it done — that is SQL with extra steps, not a document model. DBMigrateAIPro can fold 1:N children into their parent as embedded arrays so the data is shaped the way MongoDB is meant to be queried.
Many tools route data through CSV and land every value as a string, corrupting money and dates. We derive a typed transport schema so NUMBER(p,s) arrives as exact Decimal128 and timestamps as real datetimes.
A join table with two foreign keys has no single owner, so embedding it into one parent would double-count. These are kept as standalone collections, with a logged reason — count integrity is preserved.
A parent with a huge child set can exceed MongoDB’s 16MB BSON limit. The load is resilient: an oversized document is reported by count validation instead of crashing the run, so you see exactly what needs a different shape.
When a child row references a missing parent, embedding it would lose it. Instead the child collection is kept holding exactly the orphans — nothing is duplicated and nothing is silently dropped.
Function-based indexes are backed by hidden SYS_NC columns that are not real document fields. We skip them so you don’t get dead indexes on keys that don’t exist in the documents.
Prerequisites
- →A reachable MongoDB target (self-managed or Atlas); pymongo on the agent host
- →Source credentials for Oracle (thin-mode oracledb, no client install) or PostgreSQL
- →Network access from the DBMigrateAIPro agent to the MongoDB port (default 27017)
- →For embedding: foreign keys defined on the source (they drive the 1:N detection)
Model your data the document way
Read the deep-dive on turning foreign keys into embedded documents, or download the free desktop tool and run a proof-of-concept in under an hour.