querydrill

Learn ›Aggregation ›Grouping and accumulators

$push vs $addToSet inside $group

$addToSet$push

Same distinction as the array update operators, in a different place: $push collects every value it sees, $addToSet collects the distinct ones. Combining $addToSet with $size is the standard way to count distinct values per group.

Suppose:

User 101 bought:

Laptop
Mouse
Laptop

$push

products: {
  $push: "$product"
}

Result:

[
  "Laptop",
  "Mouse",
  "Laptop"
]

$addToSet

products: {
  $addToSet: "$product"
}

Result:

[
  "Laptop",
  "Mouse"
]

Remember:

$push
→ keep duplicates

$addToSet
→ unique values

Try it

Both, side by side, so the difference is in one output:

db.orders.aggregate([
  { $unwind: "$items" },
  {
    $group: {
      _id: "$userId",
      all: { $push: "$items.product" },
      distinct: { $addToSet: "$items.product" }
    }
  },
  { $limit: 3 }
])

all has the repeats; distinct does not. Wrap the second one in $size and you have a count of distinct products per user.

Practise this

1 exercise