The $in operator matches documents when a field equals any value in a list. Use it in $match to filter by multiple categories, statuses, or IDs in one clean query instead of writing many $or conditions.
01
Membership Test
Match any listed value.
02
Two Syntax Forms
Query filter vs expression.
03
$match Stage
Filter by multiple values.
04
Array Fields
Works on array elements too.
05
Use Cases
Categories, roles, IDs.
06
$nin Opposite
Exclude listed values.
Fundamentals
Definition and Usage
In MongoDB, the $in operator selects documents where a field’s value appears in a specified array. For example, { status: { $in: [ "active", "pending" ] } } returns every document whose status is either "active" or "pending". It is one of the most common query operators for multi-value filtering.
In aggregation expressions, { $in: [ "$role", [ "admin", "editor" ] ] } returns true or false depending on whether the field value is in the array. This is useful for adding flags or driving $cond logic.
💡
Beginner Tip
Think of $in like JavaScript’s array.includes(value), but in reverse for the query form: MongoDB checks whether the field value is included in your list. It is much cleaner than chaining multiple $eq checks with $or.
Foundation
📝 Syntax
$in has two forms depending on where you use it:
Query form (in $match or find filters)
mongosh
{ field: { $in: [ <value1>, <value2>, ... ] } }
Aggregation expression form (in $project, $cond, etc.)
mongosh
{ $in: [ <expression>, <array expression> ] }
Syntax Rules
Query form — keeps documents where the field equals at least one value in the array.
Expression form — returns true when the first operand is found in the second array.
If the field is an array, a match occurs when any element in the field array equals a listed value.
Values must match BSON types exactly (no automatic type conversion).
An empty $in array { field: { $in: [] } } matches no documents.
Use $nin for the opposite — exclude documents matching any listed value.
💡 Query Form vs Expression Form
Know which form to use based on your pipeline stage:
When $in returns true, $cond outputs "domestic". Otherwise the order is labeled "international". This pattern is common for routing, pricing, and regional rules.
Bonus — Filter by Multiple ObjectIds
$in is especially handy when fetching documents by a list of IDs:
Pass an array of ObjectId values to retrieve multiple documents in one query instead of running separate lookups for each ID.
Applications
🚀 Use Cases
Multi-value filtering — select documents by category, status, role, or region in one condition.
Batch ID lookups — fetch many documents by _id or foreign key using an array of ObjectIds.
Tag and skill matching — find articles, jobs, or users when an array field contains any target value.
Conditional labeling — use the expression form inside $cond for routing, pricing tiers, or access control flags.
🧠 How $in Works
1
MongoDB reads the field and list
In $match, it checks a field against an array of allowed values. In expressions, it evaluates a value like "$role" against an array like ["admin", "editor"].
Input
2
$in tests membership
MongoDB checks whether the field value (or any array element) equals at least one value in the list. Type and value must match exactly.
Compare
3
Result is applied in the pipeline
In $match, matching documents pass through. In expressions, true or false is stored in the output field.
Output
=
🔍
Efficient multi-value matches
You get filtered documents or boolean flags without writing long $or chains.
Wrap Up
Conclusion
The $in operator is one of the most practical tools for multi-value filtering in MongoDB. It replaces verbose $or / $eq combinations with a single readable condition, and its expression form powers membership checks inside $project and $cond.
For beginners, remember two forms: query form { field: { $in: [ ... ] } } filters documents, and expression form { $in: [ expr, array ] } returns true or false. Pair it with indexes on filtered fields for the best performance on large collections.
Use $in instead of long $or chains for the same field
Index fields you frequently filter with $in
Use expression form in $project and $cond for membership flags
Keep value types consistent (strings vs numbers vs ObjectIds)
Use $nin when you need to exclude a list of values
❌ Don’t
Pass an empty array to $in expecting all documents (it matches none)
Assume type coercion — "10" and 10 are different
Use expression form inside $match (it won’t filter as expected)
Confuse query $in with aggregation $indexOfArray
Put huge unbounded arrays in $in without considering query plan cost
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about $in
Use these points when filtering by multiple values in MongoDB.
5
Core concepts
🔍01
Membership Test
Match any listed value.
Purpose
📝02
Two Forms
Query filter vs expression.
Syntax
🛠03
$match Filter
Multi-value matching.
Usage
📦04
Array Fields
Any element can match.
Pattern
⚠05
Empty Array
{ $in: [] } matches none.
Edge case
❓ Frequently Asked Questions
$in matches documents where a field equals at least one value in a given array. In query filters it keeps matching documents. In aggregation expressions it returns true when the first value appears in the second array.
Query form: { field: { $in: [ value1, value2, ... ] } }. Aggregation expression form: { $in: [ <expression>, <array expression> ] }. The query form filters documents; the expression form returns true or false.
$in is shorter and easier to read when checking one field against several values. { status: { $in: ["active", "pending"] } } is equivalent to { $or: [ { status: "active" }, { status: "pending" } ] } but more concise.
Yes. If the field holds an array, $in matches when at least one element in that field array equals a value in the $in list. For example, tags: ["js", "node"] matches { tags: { $in: ["js"] } }.
$in keeps documents where the field matches any listed value. $nin does the opposite — it excludes documents whose field matches any value in the array.