$comment is a MongoDB query operator that attaches a label to a query predicate. It does not filter or change documents. The label shows up in logs, the profiler, and currentOp so you can trace the operation later.
Write your normal filter, add a short label, then look for that label in profiler or logs when debugging.
Write the real query predicate (find filter or $match).
Add $comment: "short-stable-label" next to the filter fields.
Run the query as usual—results stay the same.
When debugging, search profiler / logs / currentOp for that label.
Piece
Required?
Role
Query predicate
Yes
What actually filters documents
$comment
No (recommended)
Label for logs / profiler / currentOp
comment option
No
Label the whole aggregate() command
Pseudocode
Pseudocode
query = { status: "open", $comment: "dashboard-open" }
run find(query) or $match(query)
→ return matching documents // same as without $comment
server metadata for this op:
comment = "dashboard-open"
visible in logs / profiler / currentOp
Reference
Cheat Sheet
Keep these facts handy while labeling queries.
Topic
Detail
Type
Query operator (observability)
In find / $match
{ ..., $comment: "label" }
On aggregate()
aggregate(pipeline, { comment: "label" })
Affects results?
No
Visible in
Logs, system.profile, currentOp
Good label
Feature, route, or ticket id
Bad label
Passwords, tokens, PII
Try it
Live Preview
Pick a label and see the idea: the filter still matches the same orders, while the comment is stored as operation metadata.
Simulates a find with $comment: same matches, different profiler label.
Filter in the pipeline.$match keeps only open orders.
Label the predicate.$comment inside $match tags that filter.
Label the command. The second argument { comment: "..." } tags the whole aggregation.
Project for a short report.$project keeps item and status only.
Edge Cases & Pitfalls
Check these before relying on $comment in production.
results
It never filters by itself
If you forget the real predicate and only send $comment, you are not selecting by business fields. Always keep the actual match criteria.
secrets
Do not put secrets in comments
Comments can land in logs and profiler collections. Never store passwords, tokens, or personal data in the label.
naming
Use stable, searchable labels
Prefer short fixed strings like checkout-v2 over free-form sentences that change every deploy.
vs option
$comment ≠ aggregate comment option
$comment sits inside a predicate. The comment option on aggregate() labels the whole command. Use either or both on purpose.
Analysis
Performance Notes
Approach
Cost
Best for
$comment on find / $match
Tiny metadata overhead
Tracing specific filters
comment on aggregate()
Tiny metadata overhead
Tracing whole pipelines
No comment
Slightly less metadata
Only when you never need to identify the op
Comments are cheap. The expensive part is still the query itself—indexes and early $match matter far more than the label string.
Remember
Key Takeaways
Role: label a query for logs / profiler / currentOp.
Results: unchanged—observability only.
Places: find filters, $match, and aggregate comment option.
Safety: never put secrets in comment strings.
One line:$comment answers “which part of my app ran this query?”—without changing what the query returns.
Frequently Asked Questions
$comment attaches a descriptive label to a query predicate. It does not filter or change documents. The label shows up in mongod logs, the database profiler, and db.currentOp() so you can trace which app code issued the query.
No. Documents returned or modified are the same with or without $comment. It is for observability only.
Anywhere a query predicate is accepted: find(), update/delete filters, and the $match stage in aggregation. You can also pass a comment option on aggregate() to label the whole command.
$comment inside a predicate labels that filter (for example inside $match). The comment option on aggregate() labels the entire aggregation command. Both can appear in profiler output.
No. A JS comment is ignored by the language. $comment is sent to the MongoDB server and stored with the operation metadata so operators and tools can read it later.
Use a short, stable label: feature name, ticket id, or route—for example dashboard-open-orders or checkout-v2. Avoid secrets such as passwords or personal data.