Saturday, May 16, 2015

Performing MongoDB atomic updates

NoSQL databases normally don't deal with transactions. Transactions can generally be avoided with good schema design and the canonical account debit/credit transaction is not really an instant transaction, if you ever transferred your money to someone right? Anyway, you can handle transactions from your business layer if needed. Having said that, MongoDB does allow for atomic updates spanning multiple documents, but they should all be within the same collection. It is very efficient with minimal data transfer.

The MongoCollection.Update has two parts - Query and Update.
Each can be type safe and consider using Query<T> and Update<T> helper classes.

articles.Update(query, update);

//Single Update
articles.Update( Query<Article>.EQ ( a => a.Id, "123A"),
                          Update<Article>.Set ( a => a.Expires, DateTime.Today));

//Multiple Updates
articles.Update( Query<Article>.LT( a => a.Expires, DateTime.Today),
                          Update<Article>.Set ( a => a.Archived, true));


Note that this bulk update happens all server side and you don't have to fetch all the data on the client to update!

There is no concept of foreign keys and joins between different collections, but we can create "foreign keys" to other collections by embedding the ObjectId of the document in one document from a collection to another document in a different collection. To do any kind of "joins", you would have to run 2 queries to fetch the related documents between the two collections.

Thing is you need far fewer collections in NoSQL than in Relational model. Fewer Joins translates into more scalability. The trade off is redundant data being stored and more memory. But the memory is actually mitigated using sharding (and replication for data availability and failover) and actually often works out to be far more cheaper than provisioning sophisticated multi-license expensive data centers to handle terabytes of relational data.

Takeaways:

  • Your Mongo context is your implicit schema
  • Use Strongly typed collection to respect the schema
  • Use Mongo + LINQ
  • Use Update instead of Retrieve + Save


No comments:

Post a Comment