Can you output a tree structure from a view? No. CouchDB view queries return a list of values, there is no way to have them output anything other than a list. So, you have to deal with your map returning the list of all descendants of a given bucket.
You can, however, plug a _list
post-processing function after the view itself, to turn that list back into a nested structure. This is possible if your values know the _id
of their parent — the algorithm is fairly straightforward, just ask another question if it gives you trouble.
Can you grab a document by its id in the map function? No. There's no way to grab a document by its identifier from within CouchDB. The request must come from the application, either in the form of a standard GET
on the document identifier, or by adding include_docs=true
to a view request.
The technical reason for this is pretty simple: CouchDB only runs the map function when the document changes. If document A
was allowed to fetch document B
, then the emitted data would become invalid when B
changes.
Can you output all descendants without storing the list of parents of every node? No. CouchDB map functions emit a set of key-value-id pairs for every document in the database, so the correspondence between the key and the id must be determined based on a single document.
If you have a four-level tree structure A -> B -> C -> D
but only let a node know about its parent and children, then none of the nodes above know that D
is a descendant of A
, so you will not be able to emit the id of D
with a key based on A
and thus it will not be visible in the output.
So, you have three choices:
- Grab only three levels (this is possible because
B
knows that C
is a descendant of A
), and grab additional levels by running the query again.
- Somehow store the list of descendants of every node within the node (this is costly).
- Store the list of parents of every node within the node.
By design, you cannot update a CouchDB document blindly, you can only attempt to update a specific revision of a document.
For a single document, you can use a CouchDB update handler to hide this from the client as an update handler will be passed the existing document (if it exists) including its revision.
For a collection of documents, when using _bulk_docs
, you can add "new_edits": false
which will forcibly insert conflicts instead of rejection (though you'll still need to pass a _rev, it just doesn't have to be the current one).
All that said, it would be better to follow the rules. Grab the current revision of the document you would like to update, attempt to update it, if you get a 409, get the new version, merge as appropriate, and update again.
Best Answer
This is by design. To create a document, don't pass a _rev value in the body.