0
0
MongodbHow-ToBeginner · 3 min read

How to Use $redact in Aggregation in MongoDB

Use the $redact stage in a MongoDB aggregation pipeline to control document visibility by specifying conditions with $$DESCEND, $$PRUNE, and $$KEEP. It evaluates each document and its subdocuments to include or exclude them based on your rules.
📐

Syntax

The $redact stage uses an expression that returns one of three special variables to control document visibility:

  • $$DESCEND: Keep the current document and continue to check its subdocuments.
  • $$PRUNE: Remove the current document and its subdocuments from the output.
  • $$KEEP: Keep the current document and all its subdocuments without further checks.

The expression is usually a $cond or other conditional operator that decides which variable to return.

json
{
  $redact: {
    $cond: {
      if: <condition>,
      then: "$$DESCEND" /* or "$$KEEP" */,
      else: "$$PRUNE"
    }
  }
}
💻

Example

This example shows how to use $redact to filter documents based on a user's clearance level stored in the document. Documents with a level field less than or equal to 3 are kept; others are pruned.

javascript
db.secrets.aggregate([
  {
    $redact: {
      $cond: {
        if: { $lte: ["$level", 3] },
        then: "$$DESCEND",
        else: "$$PRUNE"
      }
    }
  }
])
Output
[ { "_id": 1, "level": 2, "secret": "Low level secret" }, { "_id": 2, "level": 3, "secret": "Medium level secret" } ]
⚠️

Common Pitfalls

Common mistakes when using $redact include:

  • Not returning one of the special variables $$DESCEND, $$KEEP, or $$PRUNE, which causes errors.
  • Using $redact without understanding it processes documents recursively, which can impact performance.
  • Confusing $$DESCEND and $$KEEP: $$DESCEND continues checking subdocuments, while $$KEEP keeps everything below without further checks.

Example of wrong usage and fix:

json
// Wrong: missing special variable
{
  $redact: {
    $cond: {
      if: { $eq: ["$status", "public"] },
      then: true,
      else: false
    }
  }
}

// Right: use $$KEEP and $$PRUNE
{
  $redact: {
    $cond: {
      if: { $eq: ["$status", "public"] },
      then: "$$KEEP",
      else: "$$PRUNE"
    }
  }
}
📊

Quick Reference

VariableMeaning
$$DESCENDKeep current document and check subdocuments
$$KEEPKeep current document and all subdocuments without further checks
$$PRUNERemove current document and all subdocuments

Key Takeaways

Use $redact in aggregation to filter documents based on conditions with $$DESCEND, $$KEEP, and $$PRUNE.
Always return one of the special variables to control document visibility correctly.
Understand that $redact processes documents recursively, which can affect performance.
Use $cond or other expressions inside $redact to define your filtering logic clearly.