I use something similar to your second option, but without a version attribute.
First, try to keep your changes in things that are easy to make backward compatible - changing the primary key is the worst case scenario.
Deleting a field is very simple - just stop writing to this field as soon as a version that does not require this is launched on all servers.
Adding a field requires that you never write this object with code that will not save this field. If you cannot deploy the new version everywhere immediately, use an intermediate version that supports saving the field before you deploy the version that requires it.
Changing a field is simply a combination of these two operations.
With this approach, changes are applied as necessary - they are written using the new version, but they allow you to read the old version with default values ββor derivatives for the new field.
You can use the same code to update all records at the same time, although this may not be acceptable for a large dataset.
Changing the primary key can be handled the same way, but it can become really complicated depending on which nosql system you are using. You are probably stuck in developing custom migration code.
Tom clarkson
source share