I need to implement a feature where there's an event schedule page. Initially, the first 20 events are shown starting from today. When the user scrolls down to the bottom, the next 20 events are fetched. Additionally, the user can search for events by entering some text in a search field.
The frontend implementation is fairly simple. However, what's hard is the backend side where I need to find a way to handle recurring events with pagination. I have come up with a few solutions, but none of them are cheap enough. I'm using Elasticsearch for this.
Solution 1: Storing each recurring event instance as a separate document
Let’s say we have an event that occurs daily for a year, then we’ll store 365 instances of that event in Elasticsearch.
- Advantages: Doing a search with pagination is quite easy this way.
- Drawbacks:
- First, there’s a problem with infinite projection (recurring events that never end). It can be solved by only storing the recurring event instances for 2 years initially, and then there'll be a scheduled task that will create new required occurrences every day.
- Second, creating, updating, and deleting can be costly. Imagine creating/updating/deleting hundreds of documents at once.
This is the solution I believe Google Calendar is currently using. For example, I tried creating an event that repeats daily infinitely in Google Calendar, but I ended up only being able to search for it in two years' time.
Solution 2: Storing only the original recurring event as a single document
Let’s say we have an event that occurs daily for a year, then we’ll only store 1 instance of that event in Elasticsearch with RRULE
. And after having the query results from Elasticsearch, I'll do some postprocessing to expand the recurring event into multiple events and do the pagination afterwards.
- Advantages: No duplication of recurring event instances. Thus, no worry about endless recurring events, and creating, updating & deleting recurring events should be really cheap.
- Drawbacks:
- Doing post-pagination can be costly, especially when we have a large number of recurring events. The reason for that is we don't know beforehand if a recurring event should appear in the final search results or not, so we'll have to expand every existing recurring event, and then do the pagination.
- We're not utilizing Elasticsearch's built-in pagination.
I'm sure there's a better way to do this. Any idea/suggestion is greatly appreciated. The most important (also the hardest) thing about this is achieving pagination.
Thanks.