Я использую что-то похожее на ваш второй вариант, но без атрибута версии.
Во-первых, постарайтесь сохранить свои изменения в вещах, которые легко сделать обратно совместимыми - изменение первичного ключа является наихудшим сценарием для этого.
Удаление поля легко - просто прекратите записьв это поле, когда все серверы работают с версией, которая не требует этого.
Добавление поля требует, чтобы вы никогда не писали этот объект, используя код, который не сохранит это поле.Если вы не можете развернуть новую версию везде сразу, используйте промежуточную версию, которая поддерживает сохранение поля, перед развертыванием версии, которая требует его.
Изменение поля - это просто комбинация этих двух операций.
При таком подходе изменения применяются по мере необходимости - пишите с использованием новой версии, но разрешите чтение старой версии с значениями по умолчанию или производными значениями для нового поля.
Вы можете использовать тот же код дляобновите все записи одновременно, хотя это может быть неприемлемо для большого набора данных.
Изменение первичного ключа может быть обработано таким же образом, но может стать действительно сложным в зависимости от используемой вами системы nosql.В этом случае вы, вероятно, застряли при разработке пользовательского кода миграции.