MongoDB $setIsSubset Operator

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

What Is $setIsSubset?

$setIsSubset is a MongoDB aggregation expression that returns true when the first array is a subset of the second—every unique value in A also appears in B. Order and duplicates are ignored. Equal arrays also return true.

Remember
$setIsSubset = is A ⊆ B ?

{ $setIsSubset: [ <arrayA>, <arrayB> ] }

{ $setIsSubset: [ [1, 2], [1, 2, 3] ] }     → true
{ $setIsSubset: [ [1, 2], [1, 3] ] }        → false
{ $setIsSubset: [ [1, 2, 1], [2, 1] ] }     → true  (dupes ignored)
{ $setIsSubset: [ [], [1, 2] ] }            → true  (empty ⊆ any)

equal arrays → true (a set is a subset of itself)
nested arrays compared as whole elements
NeedPrefer
Is A contained in B?$setIsSubset
Same unique elements?$setEquals
Shared elements list$setIntersection

How to Use $setIsSubset in MongoDB

Pass two arrays: the candidate subset first, the larger set second.

  1. Choose an expression stage ($addFields or $project).
  2. Write { $setIsSubset: [ "$required", "$tags" ] } (A first, B second).
  3. Read the boolean: true means every required value is present in tags.
  4. To filter documents, use $match with $expr.
PieceRequired?Role
First array (A)YesCandidate subset
Second array (B)YesSuperset to test against
Result—true if A ⊆ B, else false

Pseudocode

Pseudocode
for each document:
    A = unique values of first array
    B = unique values of second array
    result = true
    for each value in A:
        if value not in B:
            result = false
            break
    emit { ..., field: result }

Cheat Sheet

Keep these facts handy while checking array subsets.

TopicDetail
TypeAggregation expression (not a find filter alone)
Syntax{ $setIsSubset: [ "$a", "$b" ] }
MeaningFirst array ⊆ second array
Order / dupesIgnored (set semantics)
Empty first arrayAlways true
Filter pattern$match + $expr + $setIsSubset
Related$setEquals, $setIntersection, $setUnion
Sample check["read","write"] ⊆ ["read","write","admin"] → true

Live Preview

Watch $setIsSubset test whether array A is contained in array B.

Simulates { $setIsSubset: [ A, B ] } with set semantics (order/dupes ignored).

Result
A = ["read", "write"]
B = ["read", "write", "admin"]

$setIsSubset → true

{ ok: true }

Worked Walkthrough — Required Permissions

A role needs ["read", "write"]. A user has ["read", "write", "admin"]. Is the requirement a subset?

Calculation
A (required) = [ "read", "write" ]
B (tags)     = [ "read", "write", "admin" ]

Check each value in A:
  "read"  in B? → yes
  "write" in B? → yes

$setIsSubset → true

If A were [ "read", "delete" ]:
  "delete" in B? → no → false

MongoDB Examples

We use two users with required permissions and tags. First we store them, then we compute the subset flag, then we filter to users who meet the requirement. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine two users. Asha has every required permission. Ben is missing delete. We save both in a collection named users.

mongosh
db.users.insertMany([
  {
    _id: 1,
    name: "Asha",
    required: ["read", "write"],
    tags: ["read", "write", "admin"]
  },
  {
    _id: 2,
    name: "Ben",
    required: ["read", "delete"],
    tags: ["read", "write"]
  }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps two documents in users. Run find() to see them:

mongosh
db.users.find()

Read those documents like this:

Field in MongoDBExample (Asha)Plain English
_id1Document id
name"Asha"User name
required["read", "write"]Permissions that must be present (array A)
tags["read", "write", "admin"]Permissions the user has (array B)
Picture
Asha:
  required  ⊆  tags ?
  {read, write} ⊆ {read, write, admin}  →  true

Ben:
  required  ⊆  tags ?
  {read, delete} ⊆ {read, write}       →  false
  (missing "delete")

How It Works

  1. Insert once. insertMany adds two user documents to users.
  2. Two arrays per user. required is the candidate subset; tags is the set to search.
  3. find() shows both rows. What you inserted is what you get back—ready for the subset check next.

Example 2 — Check Subset

Goal: add an ok boolean—is required a subset of tags?

mongosh
db.users.aggregate([
  {
    $addFields: {
      ok: {
        $setIsSubset: ["$required", "$tags"]
      }
    }
  }
]);

How It Works

  1. Read both arrays. Still using required and tags from Example 1.
  2. Pass A then B. $setIsSubset: ["$required", "$tags"] asks “is required ⊆ tags?”
  3. Set semantics. Order and duplicate values do not matter.
  4. Boolean result. Asha → true; Ben → false because delete is missing.

Example 3 — Filter with $expr

Keep only users whose required permissions are fully covered by tags.

mongosh
db.users.aggregate([
  {
    $match: {
      $expr: {
        $setIsSubset: ["$required", "$tags"]
      }
    }
  },
  {
    $project: {
      name: 1,
      required: 1,
      tags: 1
    }
  }
]);

How It Works

  1. Same subset test. Still $setIsSubset: ["$required", "$tags"] on the Example 1 data.
  2. Wrap with $expr. Aggregation operators need $expr inside $match.
  3. Keep matches only. Asha stays; Ben is dropped.
  4. Project a clean shape. Output shows name and the two arrays.

Edge Cases & Pitfalls

Check these before using $setIsSubset in production pipelines.

order

Argument order matters

[A, B] means “is A a subset of B?”. Swapping them answers a different question.

nested

Nested arrays are not flattened

["a","b"] is not a subset of [["a","b"]]. Nested arrays count as single elements.

empty

Empty first array is always true

[] ⊆ anything. That includes an empty second array.

types

Both inputs must be arrays

Non-array inputs error the pipeline. Confirm field types before comparing.

Performance Notes

ApproachCostBest for
$setIsSubset on small arraysCheap per documentTags, roles, permission lists
+ $match / $exprScan + expressionFiltering who meets requirements
Huge arraysMore comparisonsKeep permission lists lean

Subset checks on typical tag/role arrays are inexpensive compared with large sorts or joins. Filter early with $match when only some documents need the check.

Key Takeaways

  • Role: true when first array ⊆ second array.
  • Syntax: { $setIsSubset: [ A, B ] }.
  • Set rules: order and duplicates ignored.
  • Filter tip: use $match + $expr.

One line: $setIsSubset answers “does the second array contain every unique value from the first?”

Frequently Asked Questions

$setIsSubset returns true when every element in the first array also appears in the second array. It treats arrays as sets, so order and duplicates are ignored. Equal arrays also return true (a set is a subset of itself).
The syntax is { $setIsSubset: [ <array1>, <array2> ] }. It takes exactly two array expressions. Result is true when array1 ⊆ array2.
Yes. [] is a subset of every array, including another empty array. So { $setIsSubset: [ [], [1, 2, 3] ] } returns true.
$setIsSubset checks containment (A ⊆ B). $setEquals checks that two arrays contain exactly the same unique elements. Equal sets are subsets of each other.
$setIsSubset returns true or false. $setIntersection returns the shared elements as an array.
No. Nested arrays are compared as whole elements at the top level. ["a", "b"] is not a subset of [["a", "b"]].

Next: $setUnion

Merge arrays into a single set of unique values.

$setUnion 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