Best practices for updates

34 views
Skip to first unread message

erich oliphant

unread,
Apr 20, 2014, 7:04:45 PM4/20/14
to scala...@googlegroups.com
Hi, I'm using SalatDAO and have run into a few situations where using the .update(...,<case class>..) is problematic.  Namely the approach of reading into my case class, making a copy with the field updates, then 'updating' with that can cause issues when there are lots of updates happening to a document, as the one that had been read might be stale, and end up overwriting another update, since the DAO/case class is writing all the fields back out.  This can obviously be addressed via 'in-place' updates via .update(..,MongoDBObject()..) but then this gets weird as now I'm losing the case class mapping and have to do the key-value mapping by hand, but even worse, I Iose the salat type handling.  So if my 'grated' case class includes a BigDecimal, when I manually create a MongoDBObject, I have to handle this by hand (and make sure my hand rolled mapping is the same as what the grater is doing).  

So I guess my question is what's the 'best practice', do I just do updates 'by hand' (and deal with the complications) to avoid these concurrent update problems?

rktoomey

unread,
Apr 22, 2014, 7:03:54 PM4/22/14
to scala...@googlegroups.com
Hi Erich,

sorry for the delay!

You are correct, the best way to get efficient updates is to hand-tune your queries.  Yes, it is painful to do all this by hand.  Especially without optimistic locking (although Spring Data does provide an @Version annotation with the same semantics as the JPA version).  

One tactic to consider is, are you trying to update an integer field?  It's very efficient to use the $inc operator.

Another idea: if you are only updating a single document, you might decrease the chance of trying to save a stale copy by using findAndModify instead:

Another tactic is, are you trying to update embedded documents or even entries in an array?  You could break these documents out into a separate collection using a parent id and update them individually (advantage: now former array items or embedded documents can be updated separately, instead of each update affecting the serialized state of the parent object). Using this tactic, you either query for child items directly or override the find method to repopulate the parent object with the child objects when you retrieve the parent object.

If you're working with time series data, this is a very helpful blog post:

For specific advice on best practices and strategies for updating documents, I recommend the general MongoDB user forum:

(Although of course I am happy to help you with any Salat specific issues!)

Please let me know how this turns out for you.

Best,
Rose
Reply all
Reply to author
Forward
0 new messages