I have an online service running multiple application servers with a couple of collections stored in MongoDB. I work in a Continuous Deployment fashion, which basically means that code updates trigger automated tests followed by a production upgrade if all goes well (this complicates matters a bit, but the question is relevant for non-CD deployments as well I believe).
This works most of the time, but sometimes one (or more) of my core data models change, in which case an upgrade could mess up the data in memory and after that in the db.
I'll give an example:
Let's say I have a simple data object:
public class User {
private String id;
private String name;
private String[] friendsNames;
}
and now I decide to change User to be :
public class User {
private String id;
private String name;
}
and add friends as a separate collection, which stores a simple object such as:
public class Friend {
private String name;
private String friendUserId;
}
This leads to a problem. I can't upgrade my service before I change the data structure to fit the new data model, and can't change the data before I take down the service, otherwise the old version will read the new data version and get messed up.
So the only solution is to bring everything down, run some upgrade process on the db to change everything, then bring the service back up with the new code running.
So finally the question: I was wondering if there was a best practice solution to version data (specifically with Mongo if this is relevant) so that older version applications would be able to keep working with old data, and new applications would "see" the new data. I thought of something like "UserV1.1" and "UserV1.2" as class versions which would search for the appropriate class version in mongo, but don't want to "reinvent the wheel" if someone already thought this through and came up with a smart solution.
Just to be clear, I don't care about object history, I just want to be able to upgrade application versions smoothly.