I'm using update() with both the $set and $push operators simultaneously,
in conjunction with the upsert option set to true.
The idea is that for any given, document, $set will update the
entire doc in full (or just insert it if it's new) and, in the same
atomic operation, append the document to a vector for tracking
history.
Using the java driver, it looks like this:
BasicDBObject update = new BasicDBObject()
.append("$set", currentDoc)
.append("$push", new BasicDBObject().append("history", currentDoc));
collection.update(query, update, true, false);
Since "history" will grow over time, I'd like a way of partitioning
by date (currentDoc includes a $currentDate field), so that I can
purge anything older than n days in that vector, while keeping the
rest of the document as-is.
TTL indexes would be ideal, if I were maintaining the history as
separate documents in their own right.
It seems, though, that I cannot do it that way b/c of the lack of
transaction support, because the actions involve multiple documents:
I.e., doing an insert with history requires finding the latest
version of the document, moving or reinserting it with a different
_id, and finally inserting the new version.