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
$redactwithout understanding it processes documents recursively, which can impact performance. - Confusing
$$DESCENDand$$KEEP:$$DESCENDcontinues checking subdocuments, while$$KEEPkeeps 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
| Variable | Meaning |
|---|---|
| $$DESCEND | Keep current document and check subdocuments |
| $$KEEP | Keep current document and all subdocuments without further checks |
| $$PRUNE | Remove 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.