MongoDB $setDifference Operator

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $setDifference?

$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
UsePrefer
Values only in A$setDifference
Shared values$setIntersection
All unique values$setUnion

How to Use $setDifference in MongoDB

Pass two arrays. Keep what is in the first list but not the second.

  1. Choose an expression stage ($addFields or $project).
  2. Decide which array is the “starting set” (first argument).
  3. Pass { $setDifference: [ <A>, <B> ] } to subtract B from A.
  4. Swap A and B when you want the opposite leftovers.
PieceRequired?Role
Array 1YesStarting set (values you may keep)
Array 2YesValues 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 }

Cheat Sheet

Keep these facts handy while subtracting one array from another.

TopicDetail
TypeAggregation expression (returns an array)
Syntax{ $setDifference: [ a, b ] }
MeaningElements in A but not in B
ArgsExactly two arrays
DuplicatesIgnored
Nothing left[]
Sample["math","quiz","art"] − ["quiz","math"] → ["art"]

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"]

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"]

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.

mongosh
db.students.insertOne({
  _id: 1,
  name: "Asha",
  skills: ["math", "quiz", "art"],
  required: ["quiz", "math", "science"]
});

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps one document in students. Run find() to see it:

mongosh
db.students.find()

Read that document like this:

Field in MongoDBValuePlain English
_id1Document id
name"Asha"Student name
skills["math", "quiz", "art"]What she has
required["quiz", "math", "science"]What the course needs
Picture
skills:   math  quiz  art
required: quiz  math  science

skills − required → art
required − skills → science

How It Works

  1. Insert once. insertOne adds Asha’s document to students.
  2. Two arrays ready. Argument order will decide extras vs missing.
  3. find() shows the same shape. Ready for Example 2.

Example 2 — Extra Skills

Goal: find skills she has that the course does not require (skills − required).

mongosh
db.students.aggregate([
  {
    $addFields: {
      extra: {
        $setDifference: ["$skills", "$required"]
      }
    }
  }
]);

How It Works

  1. Start with skills. First argument is $skills.
  2. Subtract required. Drop any value that also appears in $required.
  3. Only art remains. math and quiz are in both lists, so they leave.
  4. Store the array. $addFields writes extra: ["art"].

Example 3 — Missing Skills

Same document, but flip the arguments: required − skills shows what the course still needs.

mongosh
db.students.aggregate([
  {
    $addFields: {
      extra: { $setDifference: ["$skills", "$required"] },
      missing: { $setDifference: ["$required", "$skills"] }
    }
  }
]);

How It Works

  1. Same lists. Still using the arrays from Example 1.
  2. Extras. skills − required → ["art"].
  3. Missing. required − skills → ["science"].
  4. 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.

Performance Notes

ApproachCostBest for
$setDifference on small arraysCheap set compareTags / skills leftovers
Huge arraysGrows with unique sizeKeep lists lean
Filter then subtractFewer docsLarge collections

Subtracting short tag lists is inexpensive. Filter early with $match when only some documents need the check.

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"]].

Next: $setEquals

Test whether two or more arrays contain the same unique elements.

$setEquals tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful