0Pricing
MongoDB Academy · Lektion

$elemMatch: Array-Unterdokumente abgleichen

Sie verwenden $elemMatch, um mehrere Bedingungen auf dasselbe Array-Element anzuwenden und falsch positive Treffer durch die Abfrage verteilter Felder zu vermeiden.

$elemMatch: Array-Unterdokumente abgleichen ist eine kostenlose MongoDB Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des MongoDB Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der MongoDB Academy-Kurs umfasst insgesamt 4 Lektionen.

Teile dieser Lektion wurden noch nicht übersetzt und werden auf Englisch angezeigt.

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!

$elemMatch Fixes the Spread Problem

$elemMatch is the solution: it constrains all conditions to match on the same single array element. MongoDB only returns a document if at least one element in the array satisfies every condition inside the $elemMatch block simultaneously. This is the correct way to query arrays of sub-documents with multiple conditions.

// Correct query with $elemMatch
db.students.find({
  scores: {
    $elemMatch: {
      subject: 'math',
      grade: 'A'
    }
  }
});
// Returns ONLY Alice (scores[0] has BOTH subject='math' AND grade='A')
// Bob is excluded: no single element satisfies both conditions

Using Range Operators Inside $elemMatch

You can use any MongoDB query operator inside $elemMatch, including range operators like $gt, $lte, and $in. This lets you express conditions like 'find any element where score is between 80 and 100 AND the subject is math'—conditions that must be true for one specific element.

// Find students with a math score above 80
db.students.find({
  scores: {
    $elemMatch: {
      subject: 'math',
      score: { $gt: 80 }
    }
  }
});
// Returns Alice (math score is 95 > 80)

// With $in inside $elemMatch
db.students.find({
  scores: {
    $elemMatch: {
      subject: { $in: ['math', 'science'] },
      grade: 'A'
    }
  }
});

Negating $elemMatch Results

You can negate an $elemMatch condition using $not to find documents where no array element satisfies all the conditions. For example, 'find students who do NOT have a math A' means 'no element satisfies both subject=math AND grade=A'. This is more precise than checking { 'scores.grade': { $ne: 'A' } } which would exclude students with any A-grade subject.

// Students who do NOT have a math A
db.students.find({
  scores: {
    $not: {
      $elemMatch: {
        subject: 'math',
        grade: 'A'
      }
    }
  }
});
// Returns Bob (his math score is D, not A)

$elemMatch in Projection

$elemMatch can also be used in the projection (second argument to find()) to return only the first array element that matches a condition. When used in projection, it's called the $elemMatch projection operator (same name, different context). It returns at most one matching element per document.

// Project only the FIRST matching scores element
db.students.find(
  { name: 'Alice' },
  {
    name: 1,
    scores: {
      $elemMatch: { subject: 'math' }
    }
  }
);
// Returns:
// { name: 'Alice', scores: [{ subject: 'math', score: 95, grade: 'A' }] }
// Only the math element is included, english is excluded

$elemMatch Projection vs $ Positional

There are two ways to project a single matching array element: the $elemMatch projection (in the projection object) lets you specify a different filter than the query filter, while the positional $ operator returns the first element matched by the query filter itself. Use $elemMatch in projection when the query filter and the element you want to project are different.

// $ positional: returns the element matched by the query filter
db.students.find(
  { 'scores.subject': 'math' },
  { 'scores.$': 1 }
);

// $elemMatch projection: different filter from query
db.students.find(
  { name: 'Alice' },  // query doesn't filter scores
  { scores: { $elemMatch: { grade: 'A' } } }  // but project only A-grade scores
);

Deeply Nested Array Sub-Documents

MongoDB supports querying arrays of arrays and deeply nested sub-documents using chained dot notation. However, $elemMatch only applies at one level deep at a time. For queries on arrays nested inside arrays, you need to chain multiple $elemMatch operators or restructure your schema to avoid excessive nesting.

// Document with nested arrays
// { courses: [{ name: 'Math', lessons: [{ id: 1, score: 95 }] }] }

// Query nested array with chained dot notation
db.curriculum.find({ 'courses.lessons.score': { $gt: 90 } });

// More precise with $elemMatch (one level)
db.curriculum.find({
  courses: {
    $elemMatch: {
      name: 'Math',
      'lessons.score': { $gt: 90 }  // dot notation within $elemMatch
    }
  }
});

Indexing for $elemMatch Queries

A multikey index on the array field supports $elemMatch queries. MongoDB uses the index to narrow down candidate documents by the indexed field values, then applies the full $elemMatch condition to confirm each candidate. To maximise index efficiency, include the most selective field of your $elemMatch condition in the index.

// Index on scores.subject for efficient $elemMatch queries
db.students.createIndex({ 'scores.subject': 1 });

// This $elemMatch query can use the index to find 'math' entries,
// then applies the grade: 'A' condition on those candidates
db.students.find({
  scores: {
    $elemMatch: {
      subject: 'math',  // <-- indexed, drives the IXSCAN
      grade: 'A'        // <-- applied after index lookup
    }
  }
});

$elemMatch With $exists and $type

You can use $exists and $type inside $elemMatch to find array elements that have optional fields or match a specific BSON type. This is useful for heterogeneous arrays where not all elements share the same shape—common in legacy data migrations or flexible event log schemas.

// Find docs with at least one scores element that has a 'notes' field
db.students.find({
  scores: {
    $elemMatch: {
      notes: { $exists: true }
    }
  }
});

// Find docs with a scores element where score is a string (data quality check)
db.students.find({
  scores: {
    $elemMatch: {
      score: { $type: 'string' }  // should be a number!
    }
  }
});

Real-World Example: E-Commerce Orders

A practical use of $elemMatch is in e-commerce: finding orders that contain a line item for a specific product with a quantity above a threshold. Without $elemMatch, the conditions would spread across different line items and produce false positives.

// Find orders containing 'product-123' with qty > 5
db.orders.find({
  lineItems: {
    $elemMatch: {
      productId: 'product-123',
      qty: { $gt: 5 }
    }
  }
});

// Also useful for status-filtered sub-documents:
db.projects.find({
  tasks: {
    $elemMatch: {
      assignee: 'alice',
      status: 'in-progress',
      priority: { $gte: 3 }
    }
  }
});

Quick Check

Test your understanding of $elemMatch for matching array sub-documents.

Lesson Recap

In this lesson you learned: $elemMatch in queries requires all conditions to match a single array element, solving the spread field problem, $elemMatch in projection returns only the first matching element, and multikey indexes support $elemMatch queries efficiently. Next up we tackle array update operators.

Häufig gestellte Fragen

Ist die Lektion „$elemMatch: Array-Unterdokumente abgleichen“ kostenlos?

Ja — der vollständige Text von „$elemMatch: Array-Unterdokumente abgleichen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des MongoDB Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der MongoDB Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „$elemMatch: Array-Unterdokumente abgleichen“?

Sie verwenden $elemMatch, um mehrere Bedingungen auf dasselbe Array-Element anzuwenden und falsch positive Treffer durch die Abfrage verteilter Felder zu vermeiden. Du übst MongoDB Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um MongoDB Academy zu starten?

Keine Vorkenntnisse erforderlich. MongoDB Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „$elemMatch: Array-Unterdokumente abgleichen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser MongoDB Academy-Lektion Code schreiben und ausführen?

Ja. Jede MongoDB Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Arrays abfragen: $all, $size und Element Match
  2. $elemMatch: Array-Unterdokumente abgleichen
  3. Arrays aktualisieren: $push, $pull, $pop, $addToSet
  4. Positionsbezogene und gefilterte positionsbezogene Updates
← Zurück zu MongoDB Academy