Search code examples
mongodbschemaschema-designmongodb-query

Recurring Events Schema w/ MongoDB


I've read some of the papers out there describing data storing methods for recurring events, but I'm still trying to wrap my head around the best practice, especially concerning MongoDB.

My main concern is to cheaply retrieve all of the events that occur within a given timeframe. My secondary concern is to modify and alter single occurrences without taking the entire event chain out of whack.

Looking at others who have asked similar questions, I have come up with a possibility. I'm not completely sold on it, and would love some pointers in the right direction.

My Idea: Within each Event document, have...

  • a recurring string field that closely matches the iCal standard
  • an "occurrences" embedded document or array field that contains changes/edit on specific occurrences (such as changing the description or start time, or canceling a single occurence).
  • an occurrence start and end field to define easily queried boundaries of the recurrence rule

Pros:

  • able to store changes and still maintain association to other events
  • easily queried, my model on the business side would have to construct each event though

Cons/Potential Problems:

  • if editing an event, and a user decides to mark changes as applying to "all events" - how to keep events that have already past from being altered

Solution

  • This seems like a good approach to me. To "keep events that have already past from being altered" simply mark them with a boolean flag that says so. You should easily be able to use that flag and the start/end date while querying and updating.

    Alternatively, you could: - set an end date for the original event - clone the event, and set a new start and end date on the new event. - empty out the occurences field on the cloned event

    Something like doing this:

    Before:

    {
        'title' : "Gin O'Clock",
        'recurrance' : 'DAILY',
        'start_date' : '2012-01-01 17:00',
        'end_date' : false,
        'occurences' : [
            { 'date' : '2012-06-03 17:00', 'title' : "Jubilee Gin O'Clock" }
        ]
    }
    

    After:

    {
        'title' : "Gin O'Clock",
        'recurrance' : 'DAILY',
        'start_date' : '2012-01-01 17:00',
        'end_date' : '2012-06-05 17:00,
        'occurences' : [
            { 'date' : '2012-06-03 17:00', 'title' : "Jubilee Gin O'Clock" }
        ]
    },
    {
        'title' : "Gin O'Clock an our earlier",
        'recurrance' : 'DAILY',
        'start_date' : '2012-06-06 16:00',
        'end_date' : false,
        'occurences' : [
        ]
    }
    

    Hope that helps!