<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris Chandler &#187; CouchDB</title>
	<atom:link href="http://chrischandler.name/category/couchdb/feed/" rel="self" type="application/rss+xml" />
	<link>http://chrischandler.name</link>
	<description>Squandering time as a raving egomaniac</description>
	<lastBuildDate>Thu, 03 Jun 2010 23:16:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>View collation for join-like behavior in CouchDB</title>
		<link>http://chrischandler.name/couchdb/view-collation-for-join-like-behavior-in-couchdb/</link>
		<comments>http://chrischandler.name/couchdb/view-collation-for-join-like-behavior-in-couchdb/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 23:53:50 +0000</pubDate>
		<dc:creator>Chris Chandler</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[collation]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://squanderingtime.com/?p=19</guid>
		<description><![CDATA[Quick overview of document collation in CouchDB for combining heterogeneous documents in the reduce phase.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been playing with CouchDB then you have probably run into the problem of having multiple documents that share a relationship, yet are complex enough that denormalizing them together doesn&#8217;t make sense.</p>
<p>For the sake of example let&#8217;s assume we have <em>Authors</em> and <em>Posts</em>.  Further, let&#8217;s assume that an Author has many Posts and that these are represented as independent documents.  The goal here is to find posts created by a specific author.</p>
<p>In SQL, this would probably be represented as a table of authors and a table posts.  Getting the aggregate result would be something along the lines of:</p>
<p><code>SELECT * from authors join posts ON authors.id = posts.author_id</code></p>
<p>This is just a simple standard JOIN, nothing very interesting about it.  However, in a document oriented system this &#8220;join&#8221; operation doesn&#8217;t really exist.  Enter view collation.</p>
<p>View collation allows us to define a map/reduce function pair that takes in multiple document types, aggregates them onto a single key value, and gives us a means to search on author id.</p>
<p>Let&#8217;s say we have an author document like the following:</p>
<p><code><br />
{'type' : 'author', 'name' : 'Chris Chandler', '_id' : '22d43eaa7e06c9c37ed3e0489401a506' }<br />
</code></p>
<p>and some  number of post documents similar to:</p>
<p><code><br />
{'type' : 'post', 'title' : 'Hello world', 'Body' : 'body text', 'Author' : '22d43eaa7e06c9c37ed3e0489401a506'  }<br />
</code></p>
<p>In this case our &#8220;foreign key&#8221; is 22d43eaa7e06c9c37ed3e0489401a506.  The mapping function would need to connect these records based on that key is something like the following:<br />
<code><br />
function(doc) {<br />
if(doc.type == 'author')<br />
{<br />
emit(doc._id , doc);<br />
}<br />
else if(doc.type == 'post')<br />
{<br />
emit(doc.author, doc);<br />
}<br />
}<br />
</code></p>
<p>This view will generate an intermediate hash table containing entries with the author&#8217;s key.  In essence we have one key (the author&#8217;s) pointing to either a post the author has created, or the author&#8217;s record itself.  To make this view answer the question &#8216;Show me all posts created by a certain author&#8217; we need to write a reduce function that removes the unnecessary author records so the final table will only contain author keys pointing to lists of posts.</p>
<p><code><br />
function(keys, values, rereduce)<br />
{<br />
var posts = [];<br />
for(var i = 0; i &lt; values.length; i++)<br />
{<br />
if(values[i].type == 'post')<br />
{<br />
posts.push(values[i]);<br />
}<br />
}</code></p>
<p><code><br />
return posts;<br />
}<br />
</code></p>
<p>The final result set appears as:<br />
<code><br />
"22d43eaa7e06c9c37ed3e0489401a506"<br />
[{_id: "d0d0ea6de45c9f4ff983f12a9fed9008", _rev: "2624588756", body: "Weee!", title: "Hello world 2", author: "22d43eaa7e06c9c37ed3e0489401a506", type: "post"}, {_id: "9de65ae955ecc2ea35055b9339f1651c", _rev: "2347078231", body: "Weee!", title: "Hello world", author: "22d43eaa7e06c9c37ed3e0489401a506", type: "post"}, {_id: "5d1ad3eed26f84879835fd47e44f7f55", _rev: "1163133569", body: "Weee!", title: "Hello world 2", author: "22d43eaa7e06c9c37ed3e0489401a506", type: "post"}, {_id: "0717ae0da9bf5919da0957268667c3f4", _rev: "1063237208", body: "Weee!", title: "Hello world 3", author: "22d43eaa7e06c9c37ed3e0489401a506", type: "post"}]</code></p>
]]></content:encoded>
			<wfw:commentRss>http://chrischandler.name/couchdb/view-collation-for-join-like-behavior-in-couchdb/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Simple stats average with CouchDB</title>
		<link>http://chrischandler.name/couchdb/simple-stats-average-with-couchdb/</link>
		<comments>http://chrischandler.name/couchdb/simple-stats-average-with-couchdb/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 00:40:11 +0000</pubDate>
		<dc:creator>Chris Chandler</dc:creator>
				<category><![CDATA[CouchDB]]></category>

		<guid isPermaLink="false">http://squanderingtime.com/?p=14</guid>
		<description><![CDATA[Edit: Thanks to Mike Keen for asking about the reduce function. It was wrong in the rereduce case but I was just lazy and hadn&#8217;t updated it. It should now work correctly in the rereduce case.
Basic statistics seem to be giving people new to Map/Reduce difficulty, including myself.  Here&#8217;s a short example on how [...]]]></description>
			<content:encoded><![CDATA[<p><em>Edit: Thanks to Mike Keen for asking about the reduce function. It was wrong in the rereduce case but I was just lazy and hadn&#8217;t updated it. It should now work correctly in the rereduce case.</em></p>
<p>Basic statistics seem to be giving people new to Map/Reduce difficulty, including myself.  Here&#8217;s a short example on how to get the average value of a group of records.</p>
<p>Suppose you have a number of records in the format:<br />
<code><br />
    { 'value' : 345 }<br />
</code></p>
<p>The goal is to write a mapping function that emits a key pair with a non-unique key and a value representing the thing you want to average.  The non-unique key is important because the values will be appended in the intermediate hash table in a list-style fashion, rather than being replaced like a normal hash table.<br />
<code><br />
function(doc) {<br />
  emit('average', doc.value);<br />
}<br />
</code></p>
<p>This mapping function makes a single key of &#8220;average&#8221; available to the reducing function.</p>
<p>Since all the numerical values we want were emitted under the &#8220;average&#8221; key the reducing function only has to sum the values and divide by the length.  In a more sophisticated case we could change the result to utilize the rereduce flag and allow incremental processing.</p>
<p><code><br />
function(key,values,rereduce)<br />
{<br />
  if(rereduce)<br />
  {<br />
    count = 0;<br />
    sum = 0;<br />
    for(i in values)<br />
    {<br />
      count += values[i]['count'];<br />
      sum += values[i]['sum'];<br />
    }</p>
<p>    return {"sum" : sum, "count" : count};<br />
  }<br />
  else<br />
  {<br />
    return {"sum" : sum(values), "count" : values.length};<br />
  }<br />
}<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://chrischandler.name/couchdb/simple-stats-average-with-couchdb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
