db.orders.aggregate([
  // Step 1: Unwind the 'users' array to get one document per user per order
  { $unwind: "$users" },
  
  // Step 2: Create a unique identifier for each user (combining order ID and user)
  {
    $project: {
      orderid: 1,
      user: "$users.name",
      items: { $ifNull: ["$users.items", []] } // Ensuring 'items' field is included, even if empty
    }
  },
  
  // Step 3: Group by user to collect all orders and unique items
  {
    $group: {
      _id: "$user",
      orders: { $addToSet: "$orderid" }, // Collect unique order ids
      unique_items: {
        $addToSet: { $map: {
            input: { $ifNull: ["$items", []] }, // Handle missing 'items' array
            as: "item",
            in: "$$item.name"
          }
        }
      }
    }
  },
  
  // Step 4: Project the final desired output format
  {
    $project: {
      user: "$_id",
      orders: 1,
      unique_items: { $size: "$unique_items" } // Count unique items
    }
  },

  // Step 5: Sort the results by user name (optional)
  { $sort: { user: 1 } }
]);

1 Like