title: Schema Migration Scripts in NoSQL Databases
body: <p>I have a active project that has always used C#, Entity Framework, and SQL Server. However, with the feasibility of NoSQL alternatives daily increasing, I am researching all the implications of switching the project to use MongoDB.</p>
  
  <p>It is obvious that the major transition hurdles would be due to being "schema-less". A good summary of what that implies for languages like C# is found <a href="https://mongodb.github.io/mongo-csharp-driver/2.3/reference/bson/mapping/schema_changes/" rel="noreferrer">here</a> in the official MongoDB documentation. Here are the most helpful relevant paragraphs (bold added):</p>
  
  <blockquote>
    <p>Just because MongoDB is schema-less does not mean that your code can
    handle a schema-less document. Most likely, if you are using a
    statically typed language like C# or VB.NET, then your code is not
    flexible and needs to be mapped to a known schema.</p>
    
    <p>There are a number of different ways that a schema can change from one
    version of your application to the next.</p>
    
    <p>How you handle these is up to you. There are two different strategies:
    Write an upgrade script. Incrementally update your documents as they
    are used. <strong>The easiest strategy is to write an upgrade script. There is
    effectively no difference to this method between a relational database
    (SQL Server, Oracle) and MongoDB.</strong> Identify the documents that need to
    be changed and update them.</p>
    
    <p>Alternatively, and not supportable in most relational databases, is
    the incremental upgrade. The idea is that your documents get updated
    as they are used. Documents that are never used never get updated.
    Because of this, there are some definite pitfalls you will need to be
    aware of.</p>
    
    <p>First, queries against a schema where half the documents are version 1
    and half the documents are version 2 could go awry. For instance, if
    you rename an element, then your query will need to test both the old
    element name and the new element name to get all the results.</p>
    
    <p>Second, any incremental upgrade code must stay in the code-base until
    all the documents have been upgraded. For instance, if there have been
    3 versions of a document, [1, 2, and 3] and we remove the upgrade code
    from version 1 to version 2, any documents that still exist as version
    1 are un-upgradeable.</p>
  </blockquote>
  
  <p>The tooling for managing/creating such an initialization or upgrade scripts in SQL ecosystem is very mature (e.g. <a href="https://msdn.microsoft.com/en-us/library/jj591621(v=vs.113).aspx" rel="noreferrer">Entity Framework Migrations</a>)</p>
  
  <p>While there are <a href="https://github.com/emirotin/mongodb-migrations" rel="noreferrer">similar tools</a> and <a href="https://derickrethans.nl/managing-schema-changes.html" rel="noreferrer">homemade scripts</a> available for such upgrades in the NoSQL world (<a href="https://stackoverflow.com/questions/1961013/are-there-any-tools-for-schema-migration-for-nosql-databases">though some believe there should not be</a>), there seems to be less consensus on "when" and "how" to run these upgrade scripts. <a href="https://blog.coinbase.com/how-we-do-mongodb-migrations-at-coinbase-47f18110d17f" rel="noreferrer">Some</a> suggest after deployment. Unfortunately this approach (when not used in conjunction with incremental updating) can leave the application in an unusable state when attempting to read existing data for which the C# model has changed.</p>
  
  <p>If </p>
  
  <blockquote>
    <p>"<a href="https://mongodb.github.io/mongo-csharp-driver/2.3/reference/bson/mapping/schema_changes/" rel="noreferrer">The easiest strategy is to write an upgrade script.</a>"</p>
  </blockquote>
  
  <p>is truly the easiest/recommended approach for static .NET languages like C#, are there existing tools for code-first schema migration in NoSql Databases for those languages? or is the NoSql ecosystem not to that point of maturity?</p>
  
  <p>If you disagree with MongoDB's suggestion, what is a better implementation, and can you give some reference/examples of where I can see that implementation in use?</p>