Thank you! This is a great example to show off CouchDB 0.11’s new
features!
You must use the fetch-related-data feature to reference documents
in the view. Optionally, for more convenient JSON, use a _list function to
clean up the results. See Couchio’s writeup on “JOIN”s for details.
Here is the plan:
-
Firstly, you have a uniqueness contstraint on your
eldocuments. If two of
them have id=2, that’s a problem. It is necessary to use
the_idfield instead ifid. CouchDB will guarantee uniqueness, but also,
the rest of this plan requires_idin order to fetch documents by ID.{ "type" : "el", "_id" : "1", "content" : "first" } { "type" : "el", "_id" : "2", "content" : "second" } { "type" : "el", "_id" : "3", "content" : "third" }If changing the documents to use
_idis absolutely impossible, you can
create a simple view toemit(doc.id, doc)and then re-insert that into a
temporary database. This convertsidto_idbut adds some complexity. -
The view emits
{"_id": content_id}data keyed on
[list_id, sort_number], to “clump” the lists with their content.function(doc) { if(doc.type == 'list') { for (var i in doc.elements) { // Link to the el document's id. var id = doc.elements[i]; emit([doc.id, i], {'_id': id}); } } }Now there is a simple list of
eldocuments, in the correct order. You can
usestartkeyandendkeyif you want to see only a particular list.curl localhost:5984/x/_design/myapp/_view/els {"total_rows":2,"offset":0,"rows":[ {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"}}, {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"}} ]} -
To get the
elcontent, query withinclude_docs=true. Through the magic of
_id, theeldocuments will load.curl localhost:5984/x/_design/myapp/_view/els?include_docs=true {"total_rows":2,"offset":0,"rows":[ {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"},"doc":{"_id":"2","_rev":"1-4530dc6946d78f1e97f56568de5a85d9","type":"el","content":"second"}}, {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"},"doc":{"_id":"1","_rev":"1-852badd683f22ad4705ed9fcdea5b814","type":"el","content":"first"}} ]}Notice, this is already all the information you need. If your client is
flexible, you can parse the information out of this JSON. The next optional
step simply reformats it to match what you need. -
Use a
_listfunction, which simply reformats the view output. People use them to output XML or HTML however we will make
the JSON more convenient.function(head, req) { var headers = {'Content-Type': 'application/json'}; var result; if(req.query.include_docs != 'true') { start({'code': 400, headers: headers}); result = {'error': 'I require include_docs=true'}; } else { start({'headers': headers}); result = {'content': []}; while(row = getRow()) { result.content.push(row.doc.content); } } send(JSON.stringify(result)); }The results match. Of course in production you will need
startkeyandendkeyto specify the list you want.curl -g 'localhost:5984/x/_design/myapp/_list/pretty/els?include_docs=true&startkey=["abc123",""]&endkey=["abc123",{}]' {"content":["second","first"]}