How to store a tree in CouchDB?
The CouchDB Wiki has a How_to_store_hierarchical_data page that describes a method, but the author says about moving nodes:
This part worries me a bit, because there’s a chance that somebody
else could add a new child node while you are in the process of moving
the sub-tree, leaving that new node dangling by itself in a sub-tree
which no longer exists. I’m not sure of the best approach to avoid
such a problem.
With such a big problem, is this really the best practice for storing trees?
I am thinking of implementing my tree by adding a parentId to each node, is it bad?
(I realize it is similar to this question, but the accepted answer there has unspecified behavior when moving nodes)
This is something I’ll be solving for BlueInk soon. Currently I’m using a materialized path and plan to use MapReduce to generate sitemap (the full tree) dynamically.
When moving branches of the tree it may be best to do a Bulk Update with “all_or_nothing: true”:
However…
…so you’d potentially end up with conflicts and you’d have to make sure your validate_doc_update didn’t prevent the change entirely.
Another alternative would be to be “eventually consistent” with the change. You could do a Bulk Update without
all_or_nothing, and continue to process each item in the MapReduce results via your client code until they’re all moved. That’s likely quite risky, though, given that someone may want to move it back, etc.Regardless of the approach keeping a history of it’s former location may be prudent in case something goes wrong.
The only trouble I see with
parent_idis the number of requests you’ll need to build the full path to the item. Though it might be possible to use a_listin addition to some simple MapReduce results that use a[parent_id, _id]key. Building the_listfunction would be none trivial, but should be doable.I’ve tested some of these approaches, but I don’t yet have it completely fleshed out. If you make it farther down any of these paths, I’d love to hear about your progress/findings.