Skip to main content

Bucket Pattern

The bucket pattern:

  • groups pieces of information into buckets
  • keep documents size predictable
  • read only data we need
  • reduce number of documents in a collection
  • improve index performance

Example:

  • track user views per book
  • each view needs: user_id, book_id, timestamp

Views: bucket:

{
  id: {
    book_id:
    month:
  }
  views: [
    {
      timestamp:
      user_id:
    },
    {
      timestamp:
      user_id:
    }
    ...
  ]
}

to query:

db.getCollection("views").find({
    "id.book_id": 31459,
    "id.month": ISODate("2023-09-30T00:00:00.000Z0
  },
  {
    _id: 0,
    view_count: { $size: "$views" }
  }
)

// Sample Output:
{
  "view_count": 2
}

// Multiply this view_count my the bucket limit

Lab:

use("bookstore");

const bucketView = [
  {
    $group: {
      _id: {
        book_id: "$book_id",
        month: {
          $dateFromParts: {
            year: { $year: "$timestamp" },
            month: { $month: "$timestamp" },
            day: 1,
          },
        },
      },
      views: {
        $push: {
          user_id: "$user_id",
          timestamp: "$timestamp",
        },
      },
    },
  },
  { 
    $set: {
      // TODO: Set the $size to the size of the $views array 
      views_count: { $size: "$views"},
    },
  },
];

print(db.views_b3dc2e60.aggregate(bucketView));