Nested complex types (normalized view)
- Last Updated: July 30, 2025
- 5 minute read
- DataDirect Connectors
- ODBC
- MongoDB 8.0
- Documentation
A subdocument nested in a subdocument
In this example, the subdocument
location contains the subdocuments city and state in
the employee collection:
{"_id": "pdn313",
"name": "Charlotte",
"manager": {"name": "Robert", "department": "Development",
"location": {"city": "Tulsa", "state": "OK"}}
}
{"_id": "gkx136",
"name": "Benjamin",
"manager": {"name": "Michael", "department": "Quality Assurance",
"location": {"city": "Dallas", "state": "TX"}}
}
The information in the employee collection would be mapped to the EMPLOYEE parent table, and the EMPLOYEE_MANAGER and the EMPLOYEE_LOCATION child tables. The EMPLOYEE table would be derived from the simple types _id and name as
follows:
| _ID | NAME |
|---|---|
| pdn313 | Charlotte |
| gkx136 | Benjamin |
The information from the manager object is
mapped to the following child table:
| NAME | DEPARTMENT | |
|---|---|---|
| pdn313 | Robert | Development |
| gkx136 | Michael | Quality Assurance |
manager object to the
EMPLOYEE_MANAGER table is handled as follows:- The table name,
EMPLOYEE_MANAGER, is derived from the name of the parent table and the object. - To establish a foreign key relationship with the parent table,
a column is generated based on the
_IDfield using the following naming convention:<parent_table>_IDFor example,
EMPLOYEE_ID. - The nested subdocuments are mapped to columns in the child
table. For example, the
namefield is mapped to theNAMEcolumn.
The information in the location object is
mapped to the following child table:
| EMPLOYEE_ID (PK & FK) | CITY | STATE |
|---|---|---|
| pdn313 | Tulsa | OK |
| gkx136 | Dallas | TX |
location object to the
EMPLOYEE_LOCATION table is handled as follows:- The table name,
EMPLOYEE_LOCATION, is derived from the name of the parent table and the object. - The
id_field is mapped asEMPLOYEE_IDto establish a foreign key relationship to the parent table. - Nested subdocuments are mapped to columns. In this example, the
cityandstatesubdocuments, which indicate the location of an employee's manager, are mapped asCITYandSTATEcolumns.
Subdocuments nested in an array
In the collection contacts, the addresses array contains the subdocuments: label, street, city, and state.
{"_id": "ajx456",
"name": "Andrea",
"addresses": [
{"label": "Home", "street": "101 Main St", "zip": "27513"},
{"label": "Work", "street": "303 Main St", "zip": "27560"}
]
}
The information in the contacts collection
would be mapped to the CONTACT parent table, and
the CONTACTS_ADDRESSES child table. The CONTACTS table would be derived from the simple types
_id and name
as follows:
| _ID | NAME |
|---|---|
| ajx456 | Andrea |
The information in the addresses array maps to the following
child table:
| CONTACTS_ID (FK) | POSITION (PK) | LABEL | STREET | ZIP |
|---|---|---|---|---|
| ajx456 | 0 | Home | 101 Main St | 27513 |
| ajx456 | 1 | Work | 303 Main St | 27560 |
addresses array to the
CONTACTS_ADDRESSES tables is handled as follows:- The table name,
CONTACTS_ADDRESSES, is derived from the name of the parent table and array. - To establish a foreign key relationship with the parent table,
a column is generated based on the
_IDfield using the following naming convention:<parent_table>_IDFor example,
CONTACTS_ID. - The primary key of the child table is a composite key formed by
the primary key of the parent table (
CONTACTS_ID) combined with the positional information contained in thePOSITIONcolumn. - Subdocuments in an array are mapped as columns. For example,
the
labelfield is mapped to theLABELcolumn.
An array nested in a document
In a separate scenario, the manager document contains the emails array in the employee
collection. The collection has the following JSON structure:
{"_id": "ajp211",
"name": "Mark",
"manager": {"name": "Cynthia",
"emails": ["cynthia@email.com", "watsonc@email.com"]}
}
{"_id": "mpc393",
"name": "Deborah",
"manager": {"name": "Cynthia",
"emails": ["cynthia@email.com", "watsonc@email.com"]}
}
{"_id": "dlm215",
"name": "Jason",
"manager": {"name": "Chris",
"emails": ["chris@email.com", "cwright@email.com"]}
}
The information in the employee collection would be mapped to the EMPLOYEE parent table, and the EMPLOYEE_EMAILS and EMPLOYEE_MANAGER
child tables. The EMPLOYEE table would be derived
from the simple types _id and name as follows:
| _ID | NAME |
|---|---|
| ajp211 | Mark |
| mpc393 | Deborah |
| dlm215 | Jason |
The information in the emails array is mapped
to the following child table:
| EMPLOYEE_ID (FK) | POSITION | EMAILS |
|---|---|---|
| ajp211 | 0 | cynthia@email.com |
| ajp211 | 1 | watsonc@email.com |
| mpc393 | 0 | cynthia@email.com |
| mpc393 | 1 | watsonc@email.com |
| dlm215 | 0 | chris@email.com |
| dlm215 | 1 | cwright@email.com |
emails array to the
EMPLOYEE_EMAILS table is handled as follows:- The table name,
EMPLOYEE_EMAILS, is derived from the name of the parent table and the array. - To establish a foreign key relationship with the parent table,
a column is generated based on the
_IDfield using the following naming convention:<parent_table>_IDFor example,
EMPLOYEE_ID. - The primary key of the child table is a composite key formed by
the primary key of the parent table (
EMPLOYEE_ID) combined with the positional information contained in thePOSITIONcolumn. - Nested arrays are mapped as columns. For example, the
emailsarray is mapped to theEMAILScolumn. Note that the emails in the following child table are those of the managers, but correspond to the employee identification number.
names subdocument is mapped to the
following child table: | EMPLOYEE_ID (PK & FK) | NAME |
|---|---|
| ajp211 | Cynthia |
| mpc393 | Cynthia |
| dlm215 | Chris |
names
subdocument to the EMPLOYEE_MANAGER table is handled as follows:- The table name,
EMPLOYEE_MANAGER, is derived from the name of the parent table and the object. - To establish a foreign key relationship with the parent
table, a column is generated based on the
_IDfield using the following naming convention:<parent_table>_IDFor example,
EMPLOYEE_ID. - The nested
namesubdocument (the name of the manager) is mapped as a column. Note that the names in the following child table are those of the managers, but correspond to the employee identification number.
An array nested in an array
In the collection offices, the departments array contains an employees
array.
{"_id": "au32",
"city": "Bedford",
"departments": [{"name": "Development",
"employees": [
{"first": "Leslie", "last": "Jacobs"},
{"first": "Emma", "last": "Alves"},
{"first": "Brad", "last": "Jones"}
]
},
{"name": "Human Resources",
"employees": [
{"first": "Joseph", "last": "Lu"},
{"first": "Margaret", "last": "Baker"},
{"first": "Chetna", "last": "Campbell"}
]
},
{"name": "IT",
"employees": [
{"first": "Caroline", "last": "Evans"},
{"first": "Markus", "last": "Campanella"},
{"first": "Jennifer", "last": "Bradley"}
]
}]
}
{"_id": "xn44",
"city": "Morrisville",
"departments": [{"name": "Development",
"employees": [
{"first": "Charles", "last": "Scott"},
{"first": "Mary", "last": "Gonzales"},
{"first": "Phil", "last": "McEnroe"}
]
},
{"name": "Operations",
"employees": [
{"first": "Rachel", "last": "Cullingford"},
{"first": "Lance", "last": "Friedman"},
{"first": "Amanda", "last": "Giachetti"}
]
},
{"name": "IT",
"employees": [
{"first": "Ingrid", "last": "Burkis"},
{"first": "Catherine", "last": "Wheeler"},
{"first": "Jacob", "last": "Williams"}
]
}]
}The information in the offices
collection would be mapped to the OFFICES parent
table, and the OFFICES_DEPARTMENTS and OFFICES_EMPLOYEES child tables. The OFFICES table would be derived from the simple types
_id and city
as follows:
| _ID (PK) | CITY |
|---|---|
| au32 | Bedford |
| xn44 | Morrisville |
The information in the departments nested array is mapped to the following child table:
| OFFICES_ID (FK) | POSITION (PK) | NAME |
|---|---|---|
| au32 | 0 | Development |
| au32 | 1 | Human Resources |
| au32 | 2 | IT |
| xn44 | 0 | Development |
| xn44 | 1 | Operations |
| xn44 | 2 | IT |
departments
nested array to the OFFICES_DEPARTMENTS table is
handled as follows:- The table name,
OFFICES_DEPARTMENTS, is derived from the name of the parent table and the array. - To establish a foreign key relationship with the parent
table, a column is generated based on the
_IDfield using the following naming convention:<parent_table>_IDFor example,
OFFICES_ID. - The primary key of the child table is a composite key
formed by the primary key of the parent table (
OFFICES_ID) combined with the positional information contained in thePOSITIONcolumn. - Nested arrays are mapped as columns. For example, the
namearray is mapped to theNAMEcolumn.
The information in the employees array is mapped to the following child table:
|
OFFICES_ID (FK) |
OFFICES_ DEPARTMENTS _POSITION | POSITION (PK) | FIRST | LAST |
|---|---|---|---|---|
| au32 | 0 | 0 | Leslie | Jacobs |
| au32 | 0 | 1 | Emma | Alves |
| au32 | 0 | 2 | Brad | Jones |
| au32 | 1 | 0 | Joseph | Lu |
| au32 | 1 | 1 | Margaret | Baker |
| au32 | 1 | 2 | Chetna | Campbell |
| au32 | 2 | 0 | Caroline | Evans |
| au32 | 2 | 1 | Markus | Campanella |
| au32 | 2 | 2 | Jennifer | Bradley |
| xn44 | 0 | 0 | Charles | Scott |
| xn44 | 0 | 1 | Mary | Gonzales |
| xn44 | 0 | 2 | Phil | McEnroe |
| xn44 | 1 | 0 | Rachel | Cullingford |
| xn44 | 1 | 1 | Lance | Friedman |
| xn44 | 1 | 2 | Amanda | Giachetti |
| xn44 | 2 | 0 | Ingrid | Burkis |
| xn44 | 2 | 1 | Catherine | Wheeler |
| xn44 | 2 | 2 | Jacob | Williams |
employees array to the
OFFICES_EMPLOYEES table is handled as follows:- The table name,
OFFICES_EMPLOYEES, is derived from the name of the parent table and the array. - The
OFFICES_IDandOFFICES_DEPARTMENTS_POSITIONcolumns establish a foreign key relationship to the parent array based on the primary key from theDEPARTMENTStable. - The primary key of the child table is a composite key formed by
the primary key of the parent table (
OFFICES_ID) combined with the positional information contained in thePOSITIONcolumn. - Nested arrays are mapped as columns. For example, the
firstarray is mapped to theFIRSTcolumn.