An embedded document is BSON type 3, an array is type 4, and their wire formats are identical: both are documents. The only difference is that an array's field names are the decimal index strings "0", "1", "2" in order — which is why array elements take the same dot notation as nested fields.
import { serialize, calculateObjectSize } from 'bson';
const book = { title: 'Dune', tags: ['scifi', 'classic'],
author: { name: 'Frank Herbert', country: 'US' } };
console.log(serialize(book).toString('hex').slice(40, 118)); // the whole tags element
console.log('array :', calculateObjectSize({ tags: book.tags }));
console.log('object :', calculateObjectSize({ tags: { 0: 'scifi', 1: 'classic' } }));047461677300210000000230000600000073636966690002310008000000636c61737369630000 array : 44 object : 44
In the hex, 04 marks the array, 7461677300 is "tags" with its null byte, 21000000 is the sub-document's 33-byte length, and the keys 30 and 31 are the strings "0" and "1". Index strings are stored in full, one reason a 100,000-element array is expensive: past index 9 every key costs two or more bytes, and the server rewrites the document on every change.
Embedding is the default relationship in MongoDB 1,815 , and dot notation makes nested data as queryable as top-level data: db.books.find({ 'author.country': 'US' }) needs no join, { 'author.country': 1 } is an ordinary index, and an index on tags becomes multikey, one entry per element (Special Index Types). Matching a whole subdocument is different — an exact comparison of serialized bytes that fails if a field is missing, extra, or out of order — so prefer dotted paths.