0Pricing
MongoDB Academy · Lesson

$elemMatch: Matching Array Sub-Documents

Learners will use $elemMatch to apply multiple conditions to a single array element, avoiding false positives from spread-field matching.

The Sub-Document Array Pattern

It's common in MongoDB to store arrays of embedded sub-documents—objects with multiple fields—inside a parent document. Examples include orders containing line items, users with multiple addresses, or students with per-subject scores. Querying these structures requires care to avoid the spread field problem where conditions are matched across different array elements.

// Example: student with per-subject scores
db.students.insertMany([
  {
    name: 'Alice',
    scores: [
      { subject: 'math', score: 95, grade: 'A' },
      { subject: 'english', score: 72, grade: 'C' }
    ]
  },
  {
    name: 'Bob',
    scores: [
      { subject: 'math', score: 68, grade: 'D' },
      { subject: 'english', score: 91, grade: 'A' }
    ]
  }
]);

The Spread Field Problem Revisited

When you filter an array of sub-documents using dot-notation fields directly, MongoDB applies each condition independently to any element in the array. The query { 'scores.subject': 'math', 'scores.grade': 'A' } would match a document if any element has subject='math' AND any (possibly different) element has grade='A'. This false-positive behavior is the spread field problem.

// Problematic query - spread field issue
db.students.find({
  'scores.subject': 'math',
  'scores.grade': 'A'
});
// Returns BOTH Alice AND Bob!
// Alice: scores[0] has subject='math', scores[0] has grade='A' -> correct match
// Bob:   scores[0] has subject='math' + scores[1] has grade='A' -> false positive!

All lessons in this course

  1. Querying Arrays: $all, $size, and Element Match
  2. $elemMatch: Matching Array Sub-Documents
  3. Updating Arrays: $push, $pull, $pop, $addToSet
  4. Positional and Filtered Positional Updates
← Back to MongoDB Academy