$setDifference

The $setDifference operator returns a set that includes elements that exist in one set but not in another set. It treats arrays as sets and ignores duplicate values and element order.

Syntax

{
  $setDifference: [ <array1>, <array2> ]
}

Parameters

Parameter Description
array1 The first array to compare. Elements unique to this array are returned.
array2 The second array to compare against the first array. Elements that exist in both arrays are excluded from the result.

Example

Let's understand the usage with sample JSON from the stores dataset.

{
  "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
  "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury",
  "sales": {
    "salesByCategory": [
      {
        "categoryName": "Sound Bars",
        "totalSales": 2120
      },
      {
        "categoryName": "Home Theater Projectors",
        "totalSales": 45004
      },
      {
        "categoryName": "Game Controllers",
        "totalSales": 43522
      },
      {
        "categoryName": "Remote Controls",
        "totalSales": 28946
      },
      {
        "categoryName": "VR Games",
        "totalSales": 32272
      }
    ]
  },
  "promotionEvents": [
    {
      "eventName": "Massive Markdown Mania",
      "discounts": [
        {
          "categoryName": "DVD Players",
          "discountPercentage": 14
        },
        {
          "categoryName": "Media Players",
          "discountPercentage": 21
        },
        {
          "categoryName": "Televisions",
          "discountPercentage": 22
        }
      ]
    }
  ]
}

Example 1: Find categories of products for sale but not discounted

The following example checks for product categories that include sales data but no discounts.

db.stores.aggregate([
  { $match: {"_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74"} },
  {
    $project: {
      name: 1,
      soldCategories: "$sales.salesByCategory.categoryName",
      discountedCategories: {
        $reduce: {
          input: "$promotionEvents",
          initialValue: [],
          in: {
            $concatArrays: ["$$value", "$$this.discounts.categoryName"]
          }
        }
      }
    }
  },
  {
    $project: {
      name: 1,
      soldCategories: 1,
      discountedCategories: 1,
      categoriesWithoutDiscounts: {
        $setDifference: ["$soldCategories", "$discountedCategories"]
      }
    }
  }
])

The query output shows categories of products that are sold but never discounted.

{
  "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
  "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury",
  "soldCategories": [
    "Sound Bars",
    "Game Controllers",
    "Remote Controls",
    "VR Games"
  ],
  "discountedCategories": [
    "DVD Players",
    "Projector Lamps",
    "Media Players",
    "Blu-ray Players",
    "Home Theater Systems",
    "Televisions"
  ],
  "categoriesWithoutDiscounts": [
    "Sound Bars",
    "Home Theater Projectors",
    "Game Controllers",
    "Remote Controls",
    "VR Games"
  ]
}

Example 2: Compare staff distribution types

The following example demonstrates how to find the difference between two hypothetical staff requirement lists.

db.stores.aggregate([
  { $match: {"_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74"} },
  {
    $project: {
      name: 1,
      requiredSkills: ["Sales", "Customer Service", "Technical Support", "Inventory Management"],
      availableSkills: ["Sales", "Customer Service", "Marketing", "Administration"],
      missingSkills: {
        $setDifference: [
          ["Sales", "Customer Service", "Technical Support", "Inventory Management"],
          ["Sales", "Customer Service", "Marketing", "Administration"]
        ]
      }
    }
  }
])

The query returns the skills that are required but not available.

{
  "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
  "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury",
  "requiredSkills": [
    "Sales",
    "Customer Service", 
    "Technical Support",
    "Inventory Management"
  ],
  "availableSkills": [
    "Sales",
    "Customer Service",
    "Marketing",
    "Administration"
  ],
  "missingSkills": [
    "Technical Support",
    "Inventory Management"
  ]
}