A short introduction of list and show handling functions in couchdb. Examples are taken from the book "CouchDB mit PHP".
Talk was given at the berlin couchdb meetup (http://berlin.couchdb.org)
2. Who am I
Oliver Kurowski
Degree in Computer Science Beuth School of applied Sciences Berlin
First Computer: Apple II 1983
Since 2003: kw automotive GmbH
Write articles in Magazines
2012: Book „CouchDB mit PHP“ (www.CouchDBmitPHP.de)
Twitter: @okurow
Mail: oliver@thinkcouchdb.com
Oliver Kurowski, @okurow
4. Transformation Functions
Documents are JSON objects
Results of views are also JSON objects
CouchDB can transfrom those JSON Objects on server side.
Shows: Transformation for documents
Lists: Transformation for views
Shows and lists are performed during request, results are not stored (like views).
Oliver Kurowski, @okurow
10. Shows:Transform Documents I
Data document (JSON): Show function in a design doc:
{ “shows“: {
“_id“: “1“, “toHTML“:“function(doc,req) {
“make“: “Audi“, var outS=‘‘;
“model“: “A3“, outS=‘<b>‘+doc.maker+‘ ‘+doc.model+‘</b><br>`;
“year“: 2000, outS+=‘Year of Prod.: ‘+doc.year+‘<br>‘;
“price“: 5.400 outS+=‘Price: ‘+doc.price;
} return outS; }“
}
Result of _show/toHTML/1 :
Audi A3
Year of Prod.: 2000
Price: 5.400
Oliver Kurowski, @okurow
11. Shows:Transform Documents II
Data document (JSON):
{
“_id“: “1“,
“author“: “Oliver Kurowski“,
“headline“: “CouchDB is great“,
“body“: “CouchDb is a great database for schemeless data“ ,
“comments“: [ {“name“: “John“, “text“: “Yes, it really is“},
{“name“: “Jane“, “text“: “What about couchbase?“} ]
}
“shows“: {
“headline“:“function(doc,req) {
var comments=0;
if (doc.comments) { comments=doc.comments.length };
var outS=‘<b>‘ + doc.headline + ‘</b> (‘ + comments + ‘ comments)`;
return outS; }“,
“detail“:“function(doc,req) {
var outS=‘<b>‘ + doc.headline + ‘</b><br>`;
outS+= doc.body + ‘<br>`;
if (doc.comments && doc.comments.length>0) {
outS+= ‘comments:<br>`;
for (var curComment in doc.comments) {
outS+=doc.comments[curComment].name+‘:<br>`;
outS+=doc.comments[curComment].text+‘<br>`;
}
}
return outS; }“
}
Oliver Kurowski, @okurow
12. Shows:Transform Documents II
Data document (JSON):
{
“_id“: “1“,
“author“: “Oliver Kurowski“,
“headline“: “CouchDB is great“,
“body“: “CouchDb is a great database for schemeless data“ ,
“comments“: [ {“name“: “John“, “text“: “Yes, it really is“},
{“name“: “Jane“, “text“: “What about couchbase?“} ]
}
“shows“: {
“headline“:“function(doc,req) {
var comments=0;
if (doc.comments) { comments=doc.comments.length };
var outS=‘<b>‘ + doc.headline + ‘</b> (‘ + comments + ‘ comments)`;
return outS; }“,
“detail“:“function(doc,req) {
var outS=‘<b>‘ + doc.headline + ‘</b><br>`;
outS+= doc.body + ‘<br>`;
if (doc.comments && doc.comments.length>0) {
outS+= ‘comments:<br>`;
for (var curComment in doc.comments) {
outS+=doc.comments[curComment].name+‘:<br>`;
outS+=doc.comments[curComment].text+‘<br>`;
}
}
return outS; }“
}
Oliver Kurowski, @okurow
13. Shows:Transform Documents II
Data document (JSON):
{
“_id“: “1“,
“author“: “Oliver Kurowski“,
“headline“: “CouchDB is great“,
“body“: “CouchDb is a great database for schemeless data“ ,
“comments“: [ {“name“: “John“, “text“: “Yes, it really is“},
{“name“: “Jane“, “text“: “What about couchbase?“} ]
}
“shows“: {
“headline“:“function(doc,req) {
var comments=0;
if (doc.comments) { comments=doc.comments.length };
var outS=‘<b>‘ + doc.headline + ‘</b> (‘ + comments + ‘ comments)`;
return outS; }“,
“detail“:“function(doc,req) {
var outS=‘<b>‘ + doc.headline + ‘</b><br>`;
outS+= doc.body + ‘<br>`;
if (doc.comments && doc.comments.length>0) {
outS+= ‘comments:<br>`;
for (var curComment in doc.comments) {
outS+=doc.comments[curComment].name+‘:<br>`;
outS+=doc.comments[curComment].text+‘<br>`;
}
}
return outS; }“
}
Oliver Kurowski, @okurow
14. Shows:Transform Documents II
Data document (JSON):
{
“_id“: “1“,
“author“: “Oliver Kurowski“,
“headline“: “CouchDB is great“,
“body“: “CouchDb is a great database for schemeless data.“ ,
“comments“: [ {“name“: “John“, “text“: “Yes, it really is“},
{“name“: “Jane“, “text“: “What about couchbase?“} ]
}
“shows“: {
“headline“:“function(doc,req) { Result of _show/headline/1 :
var comments=0; CouchDB is great (2 comments)
if (doc.comments) { comments=doc.comments.length };
var outS=‘<b>‘ + doc.headline + ‘</b> (‘ + comments + ‘ comments)`;
return outS; }“,
“detail“:“function(doc,req) {
var outS=‘<b>‘ + doc.headline + ‘</b><br>`;
outS+= doc.body + ‘<br>`;
if (doc.comments && doc.comments.length>0) {
outS+= ‘<hr>Comments:<br>`;
for (var curComment in doc.comments) {
outS+=doc.comments[curComment].name+‘:<br>`;
outS+=doc.comments[curComment].text+‘<br>`;
}
}
return outS; }“
}
Oliver Kurowski, @okurow
15. Shows:Transform Documents II
Data document (JSON):
{
“_id“: “1“,
“author“: “Oliver Kurowski“,
“headline“: “CouchDB is great“,
“body“: “CouchDb is a great database for schemeless data.“ ,
“comments“: [ {“name“: “John“, “text“: “Yes, it really is“},
{“name“: “Jane“, “text“: “What about couchbase?“} ]
}
“shows“: {
“headline“:“function(doc,req) { Result of _show/headline/1 :
var comments=0; CouchDB is great (2 comments)
if (doc.comments) { comments=doc.comments.length };
var outS=‘<b>‘ + doc.headline + ‘</b> (‘ + comments + ‘ comments)`;
return outS; }“,
“detail“:“function(doc,req) {
var outS=‘<b>‘ + doc.headline + ‘</b><br>`;
Result of _show/detail/1 :
outS+= doc.body + ‘<br>`; CouchDB is great
if (doc.comments && doc.comments.length>0) { CouchDb is a great database for schemeless data.
outS+= ‘<hr>Comments:<br>`;
for (var curComment in doc.comments) { Comments:
outS+=doc.comments[curComment].name+‘:<br>`; John:
outS+=doc.comments[curComment].text+‘<br>`; Yes, it really is
} Jane:
} What about couchbase?
return outS; }“
}
Oliver Kurowski, @okurow
16. The Request Object
Shows and lists can access the Request Object containing:
(the most interesting)
Info: Informations about the Database
Id: called document ID (null, if not given)
requested
_path: The request in parts (divided by /) as Array
headers: Header, sent from the client
userCTX: Information about the user, usefull for access limitations!
query: Parameters of the call
The field req.query allows the use of own parameters that can be used in a
show/list function.
F.e: _show/toHTML/1?showPrice=true
handled in the show function: if(req.query.showPrice==true) { ….}
Oliver Kurowski, @okurow
17. Shows:Talking Parrots
Data documents : Design document :
{ {
“_id“: “lora“, “_id“: “_design/parrot“,
“name“: “Lora LoL“, “shows{
“owner“: “Emily“, "introduce": "function(doc,req) {
“color“: [“red“ , “#ff0000“ ] , var outS='';
“languages“: [ “english“ ] if(doc) { // doc with id in database found
} outS+='<font color='+doc.color[1]+'>'+doc.name
+' belongs to '+doc.owner+'</font>';
{ if(req.query.say) {
“_id“: “polly“, if(doc.languages) {
“name“: “Polly Poll“, outS+=' and says: '+req.query.say;
“owner“: “Ernest“, }else{
“color“: [“blue“ , “#0000ff“ ], outS+='tweet';
“languages“: [ “english“ ] }
} }
} else { // no doc found
if(req.path[5]!=undefined) { // no id given
{ outS+='I dont know '+req.path[5];
“_id“: “agnus“, }else{
“name“: “Agnus Angry“, outS+='which parrot?';
“owner“: “Ernest“, }
“color“: [“grey“ , “#cococo“ ] }
} return outS; }“
}
}
Oliver Kurowski, @okurow
18. Shows: Talking Parrots
http://localhost:5984/parrots/_design/parrot/_show/introduce/
->which parrot?
http://localhost:5984/parrots/_design/parrot/_show/introduce/polly
->Polly Poll belongs to Ernest
http://localhost:5984/parrots/_design/parrot/_show/introduce/pollx
->I dont know pollx
http://localhost:5984/parrots/_design/parrot/_show/introduce/lora?say=Hello
->Lora Loll belongs to Emily and says: Hello
http://localhost:5984/parrots/_design/parrot/_show/introduce/agnus?say=Hello
->Agnus Angry belongs to Ernest tweet
Oliver Kurowski, @okurow
24. List:Transform view results I
Result of a View byPrice: A simple list function:
{"total_rows":5,"offset":0, “lists“: {
"rows":[ “asLI “:“function(head,req) {
{"id":"1","key":5.400,"value":“Audi-A3- start({'code':200,'headers':{'Content-Type':'text/html'}});
2000“}, {"id":"2","key":9.000,"value":“VW-Golf- while(row=getRow()) {
2008“}, {"id":"3","key":12.000,"value":“VW-Polo- send(‘<li>‘+row.value+‘ :‘ +row.key+‘</li>‘);
2010“}, {"id":"4","key":15.000,"value":“VW-Golf- }
2009“}, {"id":"5","key":16.000,"value":“Audi-A4- }“
2009“} ]} }
result from _list/asLi/byPrice :
• Audi-A3-2000 : 5.400
• VW-Golf-2008 : 9.000
• VW-Polo-2010 : 12.000
• VW-Golf-2009 : 15.000
• Audi-A4-2009 : 16.000
- All arguments from a view can also be used in a list call
(startkey, endkey, skip, limit etc)
- Like Shows, you have access to the request Object with all ist possibilities.
Oliver Kurowski, @okurow
25. List:Transform view results II
Different headers can be sent
“lists“: {
“asXML “:“function(head,req) {
start({'code':200,'headers':{'Content-Type':'application/xml'}});
var xmlS=‘<cars>‘;
while(row=getRow()) {
xmlS+=‘<car id=‘ + row.id + ‘>‘+row.value+‘ :‘ +row.key+‘</car>‘);
}
xmlS+=‘</cars>‘;
return xmlS;
}“
}
result from _list/asXML/byPrice :
<cars>
<car id=‘1‘>Audi-A3-2000 : 5.400</car>
<car id=‘2‘>VW-Golf-2008 : 9.000</car>
<car id=‘3‘ >VW-Polo-2010 : 12.000</car>
<car id=‘4‘>VW-Golf-2009 : 15.000</car>
<car id=‘5‘>Audi-A4-2009 : 16.000</car>
</cars>
Oliver Kurowski, @okurow