MongoDB $filter Operator

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 4 Examples
Array

What You’ll Learn

The $filter operator returns a new array with only the elements that pass a condition. It is an aggregation expression operator — like JavaScript’s Array.filter(), but inside MongoDB pipelines.

01

Array Filtering

Keep matching elements only.

02

Syntax

input, as, cond.

03

$$ Variable

Reference each item with $$as.

04

$project Stage

Shape arrays in output.

05

Use Cases

Tags, line items, scores.

06

Optional Limit

Cap how many matches return.

Definition and Usage

In MongoDB’s aggregation framework, the $filter operator selects elements from an array based on a boolean condition. You provide the source array (input), a variable name (as), and a condition (cond). MongoDB loops through each element and keeps only those where cond evaluates to true.

💡
Beginner Tip

Inside cond, reference the current array element with a double dollar sign: if as is "item", use "$$item". A single $ refers to document fields; $$ refers to variables defined in the expression.

📝 Syntax

The $filter operator takes an object with input, as, and cond:

mongosh
{
  $filter: {
    input: <array expression>,
    as: <string>,
    cond: <boolean expression>,
    limit: <number>  // optional
  }
}

Common Patterns

mongosh
// Keep strings that equal "active"
{ $eq: [ "$$tag", "active" ] }

// Keep objects where price > 100
{ $gt: [ "$$item.price", 100 ] }

// Combine conditions with $and
{ $and: [
    { $gte: [ "$$score", 70 ] },
    { $eq: [ "$$score.passed", true ] }
] }

Syntax Rules

  • input — the array to filter (field path like "$tags" or a literal array).
  • as — variable name for the current element (e.g. "item" or "tag").
  • cond — boolean expression; element is kept when this is true.
  • limit — optional; stops after collecting this many matching elements.
  • Use inside stages like $project, $addFields, or $set.
⚠️
$filter vs $match

$filter works on arrays inside a document and returns a smaller array. $match works on whole documents and removes documents from the pipeline. Use $filter when you need to trim embedded lists without dropping the parent document.

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation array expression operator
Syntax{ $filter: { input, as, cond [, limit] } }
InputArray or array expression
OutputFiltered array (or null)
Common stages$project, $addFields, $set
Basic
{
  $filter: {
    input: "$tags",
    as: "tag",
    cond: {
      $eq: ["$$tag", "sale"]
    }
  }
}

Keep matching strings

Objects
{
  $filter: {
    input: "$items",
    as: "item",
    cond: {
      $gt: ["$$item.qty", 0]
    }
  }
}

Filter object arrays

With limit
{
  $filter: {
    input: "$scores",
    as: "s",
    cond: { $gte: ["$$s", 80] },
    limit: 3
  }
}

Cap result count

Null input
{
  $filter: {
    input: null,
    as: "x",
    cond: true
  }
}

Returns null

Examples Gallery

Walk through sample data, an aggregation pipeline, and the output step by step.

📚 Product Tags

Start with a products collection and filter string tags with $project.

Sample Input Documents

Suppose you have a products collection where each document has a tags array:

mongosh
[
  {
    "_id": ObjectId("609c26812e9274a86871bc6a"),
    "name": "Laptop",
    "tags": ["electronics", "sale", "featured"]
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6b"),
    "name": "Mouse",
    "tags": ["electronics", "accessory"]
  },
  {
    "_id": ObjectId("609c26812e9274a86871bc6c"),
    "name": "Desk",
    "tags": ["furniture", "sale"]
  }
]

Example 1 — Filter Tags Equal to "sale"

Keep only tags that equal "sale" in a new field called saleTags:

mongosh
db.products.aggregate([
  {
    $project: {
      name: 1,
      saleTags: {
        $filter: {
          input: "$tags",
          as: "tag",
          cond: { $eq: [ "$$tag", "sale" ] }
        }
      }
    }
  }
])

How It Works

  • MongoDB loops through each element in tags.
  • For each element, $$tag holds the current value.
  • Elements where $$tag equals "sale" are kept; others are dropped.
  • Documents with no matching tags get an empty array [], not null.

📈 Practical Patterns

Filter arrays of objects, combine conditions, and cap results with limit.

Example 2 — Filter Line Items with Quantity > 0

When arrays contain objects, use dot notation on the $$ variable:

mongosh
db.orders.aggregate([
  {
    $project: {
      orderId: 1,
      activeItems: {
        $filter: {
          input: "$items",
          as: "item",
          cond: { $gt: [ "$$item.qty", 0 ] }
        }
      }
    }
  }
])

How It Works

$$item refers to each object in the items array. The condition { $gt: [ "$$item.qty", 0 ] } keeps only items that still have stock.

Example 3 — Combine Conditions with $and

Filter students who passed and scored at least 70:

mongosh
db.classes.aggregate([
  {
    $project: {
      className: 1,
      topStudents: {
        $filter: {
          input: "$students",
          as: "student",
          cond: {
            $and: [
              { $gte: [ "$$student.score", 70 ] },
              { $eq: [ "$$student.passed", true ] }
            ]
          }
        }
      }
    }
  }
])

How It Works

$and requires both conditions to be true. This pattern is useful when a single comparison is not enough.

Example 4 — Limit the Number of Matches

Use the optional limit field to return only the first N matching elements:

mongosh
db.products.aggregate([
  {
    $project: {
      name: 1,
      firstTwoSaleTags: {
        $filter: {
          input: "$tags",
          as: "tag",
          cond: { $eq: [ "$$tag", "sale" ] },
          limit: 2
        }
      }
    }
  }
])

How It Works

Even if more than two tags match, MongoDB stops after collecting two results. This is helpful for previews, pagination-style trimming, or performance when you only need a sample.

🚀 Use Cases

  • Tag and category cleanup — keep only relevant labels from a product or article tag list.
  • Order line items — return only in-stock or non-cancelled items from an embedded array.
  • Student or employee lists — filter nested records by score, status, or role.
  • API response shaping — trim large arrays in $project before sending data to clients.

🧠 How $filter Works

1

MongoDB reads the input array

The input expression resolves to an array — usually a field like "$tags" or "$items".

Input
2

Each element is tested

MongoDB assigns the current element to the as variable and evaluates cond using $$as.

Loop
3

Matching elements are collected

When cond is true, the element is added to the result array. Optional limit stops early.

Output
=

A trimmed array

You get a new array with only the elements that passed the condition — the original field stays unchanged unless you overwrite it.

Conclusion

The $filter operator is essential when documents store embedded arrays and you need to return only the relevant items. It keeps parent documents intact while shaping nested data — perfect for tags, line items, scores, and nested user lists.

For beginners, remember three parts: input (the array), as (the loop variable name), and cond (the test using $$variable). Place it inside $project or $addFields and you have MongoDB’s built-in array filtering.

💡 Best Practices

✅ Do

  • Use descriptive as names like "item" or "tag"
  • Reference loop variables with $$, not single $
  • Combine $and / $or for multi-condition filters
  • Use limit when you only need the first few matches
  • Keep the original array if you still need the full list elsewhere

❌ Don’t

  • Confuse $filter with the $match pipeline stage
  • Forget $$ when referencing the as variable
  • Assume a missing array returns [] — null input returns null
  • Filter huge arrays without considering performance
  • Use $filter as a top-level query operator outside expressions

Key Takeaways

Knowledge Unlocked

Five things to remember about $filter

Use these points when filtering arrays in aggregation pipelines.

5
Core concepts
📝 02

Three Parts

input, as, cond.

Syntax
🛠 03

$$ Variable

Reference each item.

Usage
🔍 04

Nested Data

Tags, items, scores.

Use case
05

Not $match

Filters arrays, not docs.

Edge case

❓ Frequently Asked Questions

$filter returns a new array containing only the elements from an input array that satisfy a condition. It is an aggregation expression operator used inside stages like $project and $addFields.
The syntax is { $filter: { input: <array>, as: <string>, cond: <expression> } }. Optionally add limit: <number> to cap how many matching elements are returned.
Use the variable name you set in as with a double dollar prefix. If as is "item", reference the current element as "$$item" inside cond.
$filter returns null when input is null or refers to a missing field. It does not throw an error.
Use $filter inside expression stages such as $project, $addFields, and $set when you need to keep only matching items from an embedded array.

Explore More MongoDB Operators

Continue with $floor, $map, and other aggregation pipeline operators.

Next: $floor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful