$setDifference is a MongoDB aggregation expression that returns the unique elements in the first array that are not in the second (relative complement). Arrays are treated as sets—duplicates are ignored.
Remember
$setDifference = first array − second array
{ $setDifference: [ <array1>, <array2> ] }
["a","c"] − ["a","b"] → ["c"]
["a","c"] − ["a","b","c"] → []
["a","b","a"] − ["b","a"] → []
exactly two arrays
duplicates ignored
output order unspecified
vs $setIntersection → values in BOTH
Decide which array is the “starting set” (first argument).
Pass { $setDifference: [ <A>, <B> ] } to subtract B from A.
Swap A and B when you want the opposite leftovers.
Piece
Required?
Role
Array 1
Yes
Starting set (values you may keep)
Array 2
Yes
Values to remove if present in array 1
Result
—
Unique leftovers from array 1 (or [])
Pseudocode
Pseudocode
for each document:
A = evaluate(array1)
B = evaluate(array2)
if A or B is null or missing:
result = null
else:
result = unique values that are in A but not in B
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while subtracting one array from another.
Topic
Detail
Type
Aggregation expression (returns an array)
Syntax
{ $setDifference: [ a, b ] }
Meaning
Elements in A but not in B
Args
Exactly two arrays
Duplicates
Ignored
Nothing left
[]
Sample
["math","quiz","art"] − ["quiz","math"] → ["art"]
Try it
Live Preview
Subtract one skill list from another and see what remains (set rules).
Simulates { $setDifference: [a, b] }.
Result
a = ["math", "quiz", "art"]
b = ["quiz", "math", "science"]
$setDifference → ["art"]
Trace
Worked Walkthrough — Extra Skills
Asha has skills math, quiz, art. The course requires quiz, math, science. What does she have that the course does not require?
Calculation
skills = ["math", "quiz", "art"]
required = ["quiz", "math", "science"]
skills − required:
math → also in required → drop
quiz → also in required → drop
art → only in skills → keep
$setDifference → ["art"]
Flip the args (required − skills) → ["science"]
Code
MongoDB Examples
We use one student with a skills list and a required list. First insert the sample, then compute extras, then flip the arguments for missing items. Run these in mongosh after inserting the sample data once.
Example 1 — Sample Data
Imagine student Asha with skills: ["math", "quiz", "art"] and required: ["quiz", "math", "science"]. We save the document in students.
Same lists. Still using the arrays from Example 1.
Extras.skills − required → ["art"].
Missing.required − skills → ["science"].
Argument order matters. A − B is not the same as B − A.
Edge Cases & Pitfalls
Check these before subtracting arrays in production pipelines.
order
Argument order changes the answer
A − B keeps leftovers from A. B − A keeps leftovers from B. Put the starting set first.
dupes
Duplicates are ignored
["a","a"] − ["a"] is []. Counts do not carry into the result.
nested
Nested arrays stay nested
["a","b"] − [["a","b"]] still returns ["a","b"]. Nested arrays are whole elements, not walked.
empty
Empty result is []
When every value in A also appears in B, you get []—not an error.
Analysis
Performance Notes
Approach
Cost
Best for
$setDifference on small arrays
Cheap set compare
Tags / skills leftovers
Huge arrays
Grows with unique size
Keep lists lean
Filter then subtract
Fewer docs
Large collections
Subtracting short tag lists is inexpensive. Filter early with $match when only some documents need the check.
Remember
Key Takeaways
Role: unique values in A but not in B.
Args: exactly two arrays.
Order: A − B ≠ B − A.
Sample: skills − required → ["art"].
One line:$setDifference answers “what unique values are in the first array but not the second?”
Frequently Asked Questions
$setDifference returns the unique elements that appear in the first array but not in the second — the relative complement of the second set with respect to the first. Example: { $setDifference: [ ["a", "c"], ["a", "b"] ] } returns ["c"].
Use { $setDifference: [ <array1>, <array2> ] }. It takes exactly two array expressions. The result is array1 minus array2.
No. It uses set semantics. Duplicates are ignored, and the result contains each remaining value at most once. Output order is unspecified.
$setDifference returns values only in the first array. $setIntersection returns values present in every input array.
Yes. A − B is not the same as B − A. Swap the arguments and you get a different set of leftovers.
$setDifference does not look inside nested arrays. A nested array counts as one whole element, so ["a"] is not the same as [["a"]].