Dot Notation

Embedded Documents and Dot Notation

There are two ways to query into an embedded document, and only one is usually right. A dotted path matches one field at any depth; a whole-document literal compares the entire subdocument, byte for byte — same fields, same values, same order.

Exact subdocument match versus a dotted path
db.books.find({ author: { name: 'Susanna Clarke', country: 'UK' } }, { title: 1, _id: 0 })
db.books.find({ author: { country: 'UK', name: 'Susanna Clarke' } }, { title: 1, _id: 0 })
db.books.find({ author: { name: 'Susanna Clarke' } }, { title: 1, _id: 0 })
db.books.find({ 'author.name': 'Susanna Clarke' }, { title: 1, _id: 0 })
Output
[ { title: 'Piranesi' } ]
[]
[]
[ { title: 'Piranesi' } ]

Reordering the keys breaks the match, and so does dropping one. Exact matching suits a small fixed structure such as a coordinate pair; everyday filtering wants dotted paths, which ignore field order and unmentioned fields and can be indexed on their own.

Dot notation needs quotes, since author.name is not a valid unquoted object key. It works to any depth ('a.b.c.d') and through arrays, where a numeric component means a position and a name component means "any element": 'editions.format' searches every edition, 'editions.0.format' only the first. A dotted path through an array of subdocuments is still matched element by element, so pair it with $elemMatch as soon as two conditions must hold together (Querying Arrays with elemMatch).