<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/" xmlns:indexing="urn:atom-extension:indexing" indexing:index="no"><access:restriction xmlns:access="http://www.bloglines.com/about/specs/fac-1.0" relationship="deny"/>
  <title>Planet CouchDB</title>
  <updated>2008-11-21T16:40:12Z</updated>
  <generator uri="http://intertwingly.net/code/venus/">Venus</generator>
  <author>
    <name>Jan Lehnardt</name>
    <email>jan@apache.org</email>
  </author>
  <id>http://planet.couchdb.com/atom.xml</id>
  <link href="http://planet.couchdb.com/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://planet.couchdb.com/" rel="alternate"/>

  <entry>
    <id>tag:damienkatz.net,2008://1.506</id>
    <link href="http://damienkatz.net/2008/11/couchdb_is_now_officially_apac.html" rel="alternate" type="text/html"/>
    <title>CouchDB is now officially Apache CouchDB</title>
    <summary>CouchDB has graduated from incubator to a top level project. This is a big step for the project. Congratulations to Chris Anderson, Jan Lehnardt, Christopher Lenz, Noah Slater and everyone else who's contributed to the project. As a special limited-time...</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>CouchDB has <a href="http://mail-archives.apache.org/mod_mbox/incubator-couchdb-dev/200811.mbox/%3c3F352A54-5FC8-4CB0-8A6B-7D3446F07462@jaguNET.com%3e">graduated from incubator to a top level project</a>. This is a big step for the project. Congratulations to Chris Anderson, Jan Lehnardt, Christopher Lenz, Noah Slater and everyone else who's contributed to the project.</p>

<p>As a special limited-time promotion,you can get free sugar and cream packets with your coffee at participating 7-11's when you say "I hope I don't spill this on the CouchDB." The promotion is not supposed to start until tomorrow, but I just tried it and it works already.</p>

<p>We are looking to release 0.9.0 in the coming weeks, which will finally include the security and validation features and will be feature complete enough to be called beta.</p></div>
    </content>
    <updated>2008-11-21T15:03:41Z</updated>
    <published>2008-11-21T14:30:41Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:www.davispj.com,2008-11-19:1227060657</id>
    <link href="http://www.davispj.com/couchdb/overview/far-away.html" rel="alternate" type="text/html"/>
    <title>CouchDB from Far Away</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1><a href="http://www.davispj.com/couchdb/overview/far-away.html">#</a> CouchDB from Far Away</h1>
<p>I read another blog post about <a href="http://incubator.apache.org/couchdb/">CouchDB</a> today. I’m not going to link to it. This post isn’t intended to be whiny drivel. Instead I thought I’d try and describe CouchDB from the point of view of someone who’s been using and developing for it for a couple months. Hopefully I can manage to paint a bit of an overall picture that tries to help new comers understand some of the more basic ideas of CouchDB.</p>
<h2>In a Nutshell</h2>
<p>Notice the ‘Nutshell’. This description is not intended to be complete or detailed. I’m merely trying to paint the overall picture. Moving on.</p>
<p>CouchDB is centered around two core ideas. A document store and Map/Reduce.</p>
<h3>Document Store</h3>
<p>The central document store component is a flat name space of documents. A document is represented in <span class="caps">JSON</span>. <span class="caps">JSON</span> looks like this:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> {
<span class="line-numbers">   2 </span>     <span class="String"><span class="String">"</span>_id<span class="String">"</span></span>: <span class="String"><span class="String">"</span>me<span class="String">"</span></span>,
<span class="line-numbers">   3 </span>     <span class="String"><span class="String">"</span>_rev<span class="String">"</span></span>: <span class="String"><span class="String">"</span>234999001<span class="String">"</span></span>,
<span class="line-numbers">   4 </span>     <span class="String"><span class="String">"</span>name<span class="String">"</span></span>: <span class="String"><span class="String">"</span>Paul Davis<span class="String">"</span></span>,
<span class="line-numbers">   5 </span>     <span class="String"><span class="String">"</span>online<span class="String">"</span></span>: {
<span class="line-numbers">   6 </span>         <span class="String"><span class="String">"</span>email<span class="String">"</span></span>: <span class="String"><span class="String">"</span>paul.joseph.davis@gmail.com<span class="String">"</span></span>,
<span class="line-numbers">   7 </span>         <span class="String"><span class="String">"</span>blog<span class="String">"</span></span>: <span class="String"><span class="String">"</span>http://www.davispj.com<span class="String">"</span></span>,
<span class="line-numbers">   8 </span>         <span class="String"><span class="String">"</span>twitter<span class="String">"</span></span>: <span class="String"><span class="String">"</span>http://twitter.com/davisp<span class="String">"</span></span>
<span class="line-numbers">   9 </span>     }
<span class="line-numbers">  10 </span> }
</pre></div>
<p>That’s it. <span class="caps">CRUD</span> operations are performed via <span class="caps">HTTP</span> using the <span class="caps">GET</span>, <span class="caps">PUT</span>, <span class="caps">POST</span>, and <span class="caps">DELETE</span> verbs. Its dead simple.</p>
<h3>Map/Reduce</h3>
<p>The second major component is the Map/Reduce framework. For those of you out there who have never heard of Google, a brief description is: Map functions take an input and give an output consisting of Key/Value pairs. A reduce function takes a set of Key/Value pairs as input and produces a single output. Yes. It’s that simple. Kind of. (More later).</p>
<p>A map functions looks like this:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Storage">function</span>(doc)
<span class="line-numbers">   2 </span> {
<span class="line-numbers">   3 </span>     <span class="Keyword">for</span>(<span class="Storage">var</span> i <span class="Keyword">in</span> doc.online)
<span class="line-numbers">   4 </span>     {
<span class="line-numbers">   5 </span>         emit(doc.<span class="SupportConstant">name</span>, doc.online[i]);
<span class="line-numbers">   6 </span>     }
<span class="line-numbers">   7 </span> }
</pre></div>
<p>Given the example <span class="caps">JSON</span> document from above, it should be clear that this is going to result in three Key/Value pairs. One for each of my online object members. That’s it.</p>
<h4>Using Map</h4>
<p>These next two sentences are very important, pay close attention: Map output is stored in ascending order according to the Key. Keys can be arbitrary <span class="caps">JSON</span> objects over which there is a very specific <a href="http://wiki.apache.org/couchdb/View_collation">sort order</a>. Now read those last two sentences three or four more times. Regardless of how many times you read them and think you understand them, chances are you’re going to end up in a situation and be taken aback about the crafty ways you can use those two properties.</p>
<p>Now that you have that idea in your head, go read Christopher Lenz’s blog post on <a href="http://www.cmlenz.net/archives/2007/10/couchdb-joins">CouchDB ‘Joins’</a>.</p>
<p>This is one of the main ideas behind using CouchDB. Understanding your data and understanding how to sort it in such away that you can get what you need by taking a slice of that sorted list. More on this later.</p>
<h4>Using Reduce</h4>
<p>While ignoring the `rereduce` parameter for now, a reduce function looks like this:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Storage">function</span>(keys, values, rereduce)
<span class="line-numbers">   2 </span> {
<span class="line-numbers">   3 </span>     <span class="Keyword">if</span>(rereduce)
<span class="line-numbers">   4 </span>     {
<span class="line-numbers">   5 </span>         <span class="Keyword">return</span> sum(values);
<span class="line-numbers">   6 </span>     }
<span class="line-numbers">   7 </span>     <span class="Keyword">else</span>
<span class="line-numbers">   8 </span>     {
<span class="line-numbers">   9 </span>         <span class="Keyword">return</span> values.<span class="SupportConstant">length</span>;
<span class="line-numbers">  10 </span>     }
<span class="line-numbers">  11 </span> }
</pre></div>
<p>Reductions have quite a few parameters but suffice it to say, this function will give us two pieces of useable information. The total number of online places in our entire database as well as the number of places per unique name. In my experience, Reduce is used to get summary type information which makes a certain amount of obvious sense. They can be used for getting a sum of values as shown, or getting the top N results for each Key emitted by a Map. I won’t say much more on the subject because use cases are either very straightforward or entirely too detailed for this post.</p>
<h4>Gory Details</h4>
<p>So we have a Map. We have a Reduce. What <strong>can’t</strong> we do with these? As it turns out there are two specific types of limits. Both types of functions must produce identical output for identical input. Reduce functions must also produce identical output regardless of the order of input as well as operate on it’s own output. The second type of limitation regards calculating values that require input from multiple documents. More on this shortly.</p>
<h4>The reason?</h4>
<p>Map/Reduce functions are calculated incrementally. If you create or update 5 records and access the Map/Reduce view, only 5 records are processed. 0 records means no processing (other than data access). This is a fairly important point people like to confuse. They think that these possibly complex Map/Reduce jobs mean hours of waiting around when in reality, construction of the Map/Reduce view is amortized over every single request made to the server. Shake your <span class="caps">SQL</span> stick at them apples (No, caching is not the same thing).</p>
<h2>Too Restrictive You Say?</h2>
<p>For anyone who is dejected after reading that last section, think of this next one as your chocolate chip cookie. Consider the semi-recent release of Google’s AppEngine. There was a <strong>lot</strong> of confusion over how it worked. I mean, how could the world’s most hugest computing giant not support count(*), sum(), or return more than a 1K records per query? Well it turns out that things in <span class="caps">SQL</span> (and other systems) actually don’t scale worth shit beyond a single node. And last I heard, Google doesn’t run on a single node so my guess is they’re probably on to something here.</p>
<p>By no means is CouchDB trying to directly emulate Google. Many might point at the Map/Reduce frame work and scream the big G. To those people, I say go design a multi-node query system that is simple and robust to errors. One of three things will happen: you’ll realize Map/Reduce is an excellent match, you’ll write something that is hugely overly complicated that everyone hates working with, or you’ll have a huge break through and define an entirely new area of distributed computation.</p>
<h2>Future Feature Fantasies</h2>
<p>I am not a core contributor. I speak for no one. I guarantee nothing. But this is my list of features I want bad enough in CouchDB that I’m planning on actually implementing them.</p>
<ol>
	<li>Extend the Map/Reduce framework to include recently published <a href="http://portal.acm.org/citation.cfm?doid=1247480.1247602">Map/Reduce/Merge</a> algorithms for distributed <strong>relational</strong> data processing. M/R/M provides for the possibility of having incrementally computed joins.</li>
	<li>Transparent physical host spanning with fault tolerance as hosts enter and exit the system at random. This part gets a bit tricky. Off the top of my head, it’d require Paxos, some sort of doc-to-node hashing, a minimum copy count algorithm etc.</li>
	<li>Erlang full text indexing. I’ve spent a lot of time trying many different solutions for full text indexing. The more I work through the different options, I’m becoming more and more convinced that a pure Erlang implementation is going to be required.</li>
	<li>Erlang Plugins. Goes with the full text indexing but also applies to other types of indexing that I’ll be needing. Things like nested containment lists etc. A good system that ends up being even easier than FireFox extension installation is going to be necessary. This is a big infrastructure and planning feature so it’ll be mostly reliant on community agreement rather than the code.</li>
</ol>
<h2>Kool-Aid</h2>
<p>If it’s not obvious, I’ve drunk my fair share of the CouchDB Kool-Aid. If you’re still a bit uncertain, I suggest you take a peek over at Chris Anderson’s excellent blog posts on the <a href="http://jchris.mfdz.com/posts/128">applications</a> of the <a href="http://jchris.mfdz.com/posts/129">future</a>. In my opinion, this is going to turn out to be a Very Big Deal™.</p></div>
    </content>
    <updated>2008-11-19T02:10:57Z</updated>
    <source>
      <id>http://www.davispj.com/</id>
      <author>
        <name>Paul Joseph Davis</name>
        <email>paul.joseph.davis@gmail.com</email>
      </author>
      <link href="http://feeds/couchdb.xml" rel="self" type="application/atom+xml"/>
      <link href="http://www.davispj.com/" rel="alternate" type="text/html"/>
      <subtitle>Semicoherent writings.</subtitle>
      <title>Paul Joseph Davis - CouchDB</title>
      <updated>2008-11-19T05:19:01Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.504</id>
    <link href="http://damienkatz.net/2008/11/the_obsessive_compulsive_time.html" rel="alternate" type="text/html"/>
    <title>Free TV Show Idea: The Obsessive Compulsive Time Traveler</title>
    <summary>I was reading a story about a guy whose been obsessed for 50 years with building a time machine to warn his dad not to smoke. Someone brought up the point that if the guy was one day successful, wouldn't...</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>I was reading a <a href="http://thephoenix.com/Boston/News/69961-Space-cowboy/">story about a guy</a> whose been obsessed for 50 years with building a time machine to warn his dad not to smoke.</p>

<p>Someone brought up the point that if the guy was one day successful, wouldn't his father have not died?</p>

<p>So that gave me the idea for a new TV show: The Obsessive Compulsive Time Traveler.</p>

<p>It's about a guy who travels back in time to make sure previous events still happen correctly, because he's afraid if he doesn't things will go wrong and the present will be wrecked. He's not right in the head, plus he's got a time machine, like a combination of <a href="http://www.usanetwork.com/series/monk/">Monk</a> and <a href="http://en.wikipedia.org/wiki/Voyagers!">Voyagers!</a>.</p>

<p>It practically writes itself. Every week he get himself into hilarious new predicaments where he has to fix the history he just broke. Plus you can learn about history and stuff ("To learn more about Sam Houston, visit your local library."). All I ask is the producer thank me when they win their Emmy.</p></div>
    </content>
    <updated>2008-11-15T22:16:54Z</updated>
    <published>2008-11-15T10:12:58Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://jchris.mfdz.com/posts/129</id>
    <link href="http://jchris.mfdz.com/posts/129" rel="alternate" type="text/html"/>
    <title>My Couch or Yours? Shareable Apps Are The Future</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I don’t have to tell you that in the long run, open source software beats closed source software, in any domain where the software is broadly useful, or in those domains where users are generally technical enough to hack their own gear. Proprietary web-servers and filesystems just can’t keep up with the free competition. As programming gets easier, the open-source advantage is moving up the stack. Microsoft burns out generations of programmers trying to keep up with Rails and Django, and they still don’t have the other advantages of freedom.</p>


	<p>I also don’t have to tell you that web development is where all the new developers are cutting their teeth these days. Middle-schoolers the world over are learning to hack by hitting “view source” and having that a-ha moment when they realize those angle brackets correspond to the web apps they use everyday.</p>


	<p>The road from kludging together <span class="caps">HTML</span> and stolen JavaScript to piloting high-level frameworks like Rails and Django is arduous and fraught with dead ends and distractions, but enough of us make it here to have created this vibrant community of enlightened hackers. We learn from each other’s code, but we still haven’t found a compelling way to share the whole stack. There are a few open-source web application success stories, like WordPress and Trac, but most of us work on applications that will die when the original business case goes away. We certainly haven’t seen an explosion of end-user friendly open-source web apps, to rival the proliferation of free development tools, frameworks, and even end-user software like browsers and media tools.</p>


	<h2>We Don’t Need No Affero</h2>


	<p>You only have to Google <span class="caps">AGPL</span> to get an idea of the tensions seething under the surface of the Free Software movement. The rub: companies have grown fat and happy using proprietary forks of open-source software to power web services. Because they aren’t distributing the software, just distributing the ability to use the software, they aren’t required to share their code under traditional licenses. It can be discouraging to pour energy in to free software, only to see big companies turn a handsome profit with it, and fail to contribute back to the community.</p>


	<p>Some say the solution is to require source distribution to accompany usage distribution. I say the solution is to out-compete the applications that don’t distribute their source. If we build apps that derive a lot of value from the fact that they can run locally or over a network, and we provide an easy way for users to share the applications, I think we can give people a reason to prefer freedom over convenience. Once users expect the benefits that come from taking ownership of their data <em>and their application code</em>, they’ll look at closed-source web apps as dinosaurs.</p>


	<h2>CouchDB Rocks, Duh</h2>


	<p>I’m not saying it’s the only way, but I will say that CouchDB is uniquely positioned to open up this new space. The <a href="http://en.wikipedia.org/wiki/Affordance">affordances</a> it creates around sharing apps and data make the opportunity cost of <em>not</em> sharing your applications and data higher than the costs of doing so. If you’re interested in my thoughts about the technical ins and outs of shareable apps, I just posted today on <a href="http://mail-archives.apache.org/mod_mbox/incubator-couchdb-user/200811.mbox/%3ce282921e0811120901n5c01da67l7ab3d2a517c774c4@mail.gmail.com%3e">the topic of peer-to-peer apps</a> on the <a href="http://incubator.apache.org/couchdb/community/lists.html">CouchDB mailing list</a>.</p>


	<h2>Let’s Do It!</h2>


	<p>If you just want to get down and dirty, and have a copy of the latest CouchDB trunk, let’s install my CouchDB Twitter client. Once you’ve got CouchDB installed and running on your local machine, installing it should take about a minute.</p>


	<p>Let’s do this step by step – with screenshots!</p>


	<p>First, go to <a href="http://127.0.0.1:5984/_utils/">your local machine’s CouchDB futon</a> and create a database.</p>


	<p><img alt="" src="http://img.skitch.com/20081114-8fbrwqxk8yn9ygphpkbb6j4sia.jpg"/></p>


	<p><br class="clear"/></p>


	<p>Now go to the Replicator, where we’ll enter the information we need to copy the CouchDB Twitter Client from my public database.</p>


	<p><img alt="" src="http://img.skitch.com/20081114-j1ue22mik3x8k8abph4jyxqmfw.jpg"/>
<br class="clear"/></p>


	<p>The remote database is <a href="http://jchris.mfdz.com:5984/twitter-client-design">http://jchris.mfdz.com:5984/twitter-client-design</a> (I created a special database with just the application code, because in this case the Twitter client tends to accumulate quite a lot of information over time.) There’s a sad bug that was introduced for a few revs of CouchDB’s trunk, having to do with <span class="caps">URL</span> escaping. It’s fixed now so if replicating doesn’t work, try running svn up and rebuilding before you retry replication.</p>


	<p>Now you have the app! Lets use it. Go back to the “Overview” page (the one you started on) and click into the twitter-client db.  Now choose “Design documents” from the drop down menu.</p>


	<p><img alt="" src="http://img.skitch.com/20081114-cadxmyfxi4msy4e91thewd3yu7.jpg"/>
<br class="clear"/></p>


	<p>Now click the _design/twitter-client document, and you’ll be happy you did because boy is it awesome! All it takes to enter the application is to click index.html.</p>


	<p><img alt="" src="http://img.skitch.com/20081114-fyc8kxseadid9n57ya7tta968.jpg"/>
<br class="clear"/></p>


	<p>And this is what it should look like, only with your friends’ updates instead of mine. If you don’t have a Twitter account, there won’t be anything to see here. There’s also a strange failure mode for some users where it just seems totally broken. This might be due to too many Twitter <span class="caps">API</span> accesses, so if you’re gung-ho, try quitting your other Twitter clients and give it an hour or so. If it still doesn’t work, well, you’ve got the source code all in that design document!</p>


	<p><img alt="" src="http://img.skitch.com/20081114-t5gqx4djp2j27h947msshtrwt9.jpg"/>
<br class="clear"/></p>


	<p>Note that you can add standing searches to your timeline by click the star in the lower-left.</p>


	<p>Enjoy!</p></div>
    </summary>
    <updated>2008-11-14T01:54:38Z</updated>
    <source>
      <id>http://jchris.mfdz.com/posts</id>
      <author>
        <name>Chris Anderson</name>
      </author>
      <link href="http://jchris.mfdz.com/posts" rel="alternate" type="text/html"/>
      <link href="http://jchris.mfdz.com/xml/rss20/feed.xml" rel="self" type="application/rss+xml"/>
      <title>Daytime Running Lights : Coding</title>
      <updated>2008-11-21T16:40:11Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.503</id>
    <link href="http://damienkatz.net/2008/11/news_at_couch.html" rel="alternate" type="text/html"/>
    <title>News at Couch</title>
    <summary>Welcome to another installment of News at Couch, our review of what's new with, on and around CouchDB. News at Couch - November 2008...</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><blockquote><div>Welcome to another installment of News at Couch, our review of what's new with, on and around CouchDB.</div></blockquote>
<a href="http://jan.prima.de/~jan/plok/archives/160-News-at-Couch-November-2008.html">News at Couch - November 2008</a></div>
    </content>
    <updated>2008-11-09T18:19:16Z</updated>
    <published>2008-11-09T18:16:09Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://jan.prima.de/~jan/plok/archives/160-guid.html</id>
    <link href="http://jan.prima.de/~jan/plok/archives/160-News-at-Couch-November-2008.html" rel="alternate" type="text/html"/>
    <title>News at Couch – November 2008</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p><img alt="couchdb-logo-128-cropped.png" border="0" class="inline" height="71" src="http://jan.prima.de/~jan/plok/uploads//couchdb-logo-128-cropped.png" style="border: 0px;" width="127"/>Welcome to another installment of <em>News at Couch</em>, our review of what’s new with, on and around <a href="http://couchdb.org/">CouchDB</a>.</p>

<hr/>

<blockquote>
  <p>What’s the most interesting new idea you’ve seen in the field of web development in the past year?</p>
  
  <blockquote>
    <p>New database architectures: CouchDB and friends.</p>
  </blockquote>
</blockquote>

<p>— <a href="http://futureofwebapps.wordpress.com/2008/10/15/fowa-pre-interview-tim-bray/">Tim Bray</a></p>

<hr/>

<p><a href="http://kore-nordmann.de/">Kore Nordmann</a> looks at how to <a href="http://kore-nordmann.de/blog/couchdb_a_use_case.html">model users, groups and permissions with CouchDB</a>.</p>

<p>Back in August, yours truly presented CouchDB at the BBC. <a href="http://barkingiguana.com/2008/08/30/jan-lenhardt-talks-to-the-bbc-about-couchdb">They shot a video</a>.</p>

<p><a href="http://jchris.mfdz.com/">Chris</a> <a href="http://jchris.mfdz.com/posts/119">tries</a> to do <a href="http://wikis.sun.com/display/WideFinder/The+Benchmark">Wide Finder</a> in CouchDB.</p>

<p>Amazing <a href="http://aimee.mychores.co.uk">Aimee</a> has a seven part series on CouchDB with Rails:  <a href="http://aimee.mychores.co.uk/2008/09/07/post/320/">One</a>, <a href="http://aimee.mychores.co.uk/2008/09/07/post/322/">two</a>, <a href="http://aimee.mychores.co.uk/2008/09/07/post/323/">three</a>, <a href="http://aimee.mychores.co.uk/2008/09/07/post/325/">four</a>, <a href="http://aimee.mychores.co.uk/2008/09/07/post/327/">five</a>, <a href="http://aimee.mychores.co.uk/2008/09/07/post/328/">six</a>, <a href="http://aimee.mychores.co.uk/2008/09/07/post/332/">seven</a>. Wow. Thanks Aimee!</p>

<p><a href="http://batok.blogspot.com/">Domingo</a> <a href="http://batok.blogspot.com/2008/09/new-attachment-handling-in-couchdb.html">looks at</a> <a href="http://code.google.com/p/couchdb-python/">couchdb-python’s</a> new attachment support contributed by (again) by yours truly.</p>

<p><a href="http://www.benatkin.com/">Ben Atkin</a> <a href="http://www.benatkin.com/weblog/?p=116">uses CouchDB from FireBug</a>, way cool!</p>

<p>Use <a href="http://www.cestari.info/2008/9/16/mod_couch-embedding-ecouch-client-for-couchdb-in-ejabberd">CouchDB with ejabberd</a>, by <a href="http://www.cestari.info/">cstar</a>.</p>

<p>Mikeal Rogers releases <a href="http://code.google.com/p/pouch/">pouch</a>, a lightweigh CouchDB library for Python, aptly named by <a href="http://www.azarask.in/blog/">Aza Raskin</a>(!).</p>

<p><a href="http://www.nearinfinity.com/">Scott Leberknight</a> writes about <a href="http://www.nearinfinity.com/blogs/page/sleberkn?entry=polyglot_persistence">Polyglot Persistence</a>.</p>

<p><a href="http://horicky.blogspot.com">Ricky Ho</a> of Adobe takes a closer <a href="http://horicky.blogspot.com/2008/10/couchdb-implementation.html">look at CouchDB’s internals</a>.</p>

<p><a href="http://www.arachnion.de/">Volker</a> got a nice <a href="http://www.splitbrain.org/blog/2008-10/19-barcamp_berlin_3">review</a> for his CouchDB talk at BarCampBerlin a few weeks ago. I was there, it was pretty good!</p>

<p><a href="http://www.ibuildings.com/blog/authors/Michael-Stillwell">Michael Stillwell</a> of <a href="http://www.ibuildings.com/">iBuildings</a> <a href="http://www.ibuildings.com/blog/archives/1291-Some-thoughts-on-CouchDB.html">reviews my presentation about CouchDB and explains CouchDB and MapReduce in one go</a>!</p>

<p><a href="http://github.com/arunthampi/activecouch/wikis/how-to-use-activecouch-with-rails">How to use ActiveCouch with Rails</a> by <a href="http://arunthampi.wordpress.com/">Arun Thampi</a></p>

<p><a href="http://upstream-berlin.com/">Alex</a> <a href="http://upstream-berlin.com/2008/10/27/couch-potato-unleashed-a-couchdb-persistence-layer-in-ruby/">unveils CouchPotato</a>, ActiveCouch’s arch rival with some pretty nifty Rails plugins already built in (acts_as versioned e.g.).</p>

<p>My friend <a href="http://vmx.cx/">Volker</a> <a href="http://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb:2008-10-26:en,CouchDB,Python,geo">released GeoCouch</a> a Geo Spatial indexer for CouchDB. Woot!</p>

<p><a href="http://books.couchdb.org/relax/">The Book</a> of course :-)</p>

<p><a href="http://jchris.mfdz.com/">Chris</a> <a href="http://jchris.mfdz.com/code/2008/10/standalone_applications_with_co">blogs about using CouchDB</a> as an app-server with p2p semantics. Me want!</p>

<p>Chris also did a tech-talk on CouchDB in New York. <a href="http://blog.arc90.com/2008/11/couchdb_tech_talk_by_chris_and.php">They taped it</a>!</p>

<p>Ok, this is a big one, <a href="http://www.lixo.org/">Carlos</a> <a href="http://www.lixo.org/archives/2008/11/02/announcing-lotsofwordscom/">puts a few Wikipedia languages into CouchDB</a> (120 GB in total) and puts  a minimalist jQuery-powered interface on top for translations and <a href="http://lotsofwords.com/">calls it “Lots of Words”</a>. Neat!</p></div>
    </content>
    <updated>2008-11-09T17:01:56Z</updated>
    <category term="couchdb"/>
    <category term="Nerdery"/>
    <author>
      <name>Jan</name>
      <email>jan@apache.org</email>
    </author>
    <source>
      <id>http://jan.prima.de/~jan/plok/</id>
      <logo>http://jan.prima.de/~jan/plok/templates/default/img/s9y_banner_small.png</logo>
      <link href="http://jan.prima.de/~jan/plok/" rel="alternate" type="text/html"/>
      <link href="http://jan.prima.de/plok/feeds/categories/9-CouchDB.rss" rel="self" type="application/rss+xml"/>
      <title>plok - couchdb</title>
      <updated>2008-11-15T10:40:05Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.502</id>
    <link href="http://damienkatz.net/2008/11/happy_halloween.html" rel="alternate" type="text/html"/>
    <title>Happy Halloween!</title>
    <summary>Nifty CouchDB Jack-O-Lantern by Chris Anderson....</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p><img src="http://img.skitch.com/20081101-mc7jyyx7nndquq995gmjpa9wci.jpg"/></p>

<p>Nifty CouchDB Jack-O-Lantern by <a href="http://jchris.mfdz.com/">Chris Anderson</a>.</p></div>
    </content>
    <updated>2008-11-01T11:03:43Z</updated>
    <published>2008-11-01T10:58:43Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://jchris.mfdz.com/posts/128</id>
    <link href="http://jchris.mfdz.com/posts/128" rel="alternate" type="text/html"/>
    <title>Standalone Applications with CouchDB</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p><strong>Update:</strong> I’ve relaunched <a href="http://jchris.mfdz.com:5984/blogdb/_design%2Fcouchdb-example-blog/index.html">the example blog on this blog’s host machine</a> It should stay up for a while. Please write a post or two!</p>


	<p>Over the last few days I’ve polished up my notion that CouchDB can be a perfectly viable application host, all on its own, without any 3rd tier between database and client. That is, CouchDB is capable of serving standalone applications. These standalone CouchDB applications can be deployed to any working CouchDB node and used from any browser.</p>


	<p>Encapsulating business logic in a Ruby or Python middleware framework like Merb or Django is no longer necessary. Between CouchDB’s views, its security model and validations, and the new _external server, developers will have everything they need to present fully functional, responsive, and dare I say <strong>scalable</strong>, web applications.</p>


	<p>Full disclosure: I’m an Apache CouchDB committer, but these views are not a result of that work, rather they are the reason I was driven to join the community in the first place.</p>


	<p>Of course, in this dream world of logarithmically scalable <span class="caps">JSON</span> and Ajax web applications, all users have to bring is a browser. However, those users who run local CouchDB nodes can stay connected to the mothership via replication, empowering not only offline use, but an explosion in open source web applications. Standalone CouchDB applications travel with the data they manage, and data can be replicated between peer nodes. Users will be free to modify and share the tools they use to manage their data, as well as the data itself.</p>


	<p><a href="http://www.2skinnypros.com/blog1/archive/2006_12_01_archive_index.html"><img alt="" src="http://img.skitch.com/20081031-gmrberrshd66x2285teumg1j6c.png"/></a></p>


	<p>Thinking of peer-based application replication takes me back to <a href="http://en.wikipedia.org/wiki/LBJ_High_School">Austin’s science magnet, <span class="caps">LBJ</span> High School.</a> As freshman, my friends and I would share little video games between the TI-85 graphing calculators we were required to carry. Two calculators could connect by one of those smaller-than-headphone minijack cables, and we’d share Physics cheat sheets, Hangman, some text-based adventures, and at the height of our powers, I believe there may have been a Doom clone running.</p>


	<p>The TI-85 programs were in Basic, so everyone was always hacking each others hacks. Perhaps the most ridiculous program was a version of Spy Hunter that you <strong>controlled with your mind</strong>. The idea was if you could influence the <strong>pseudo</strong> random number generator by concentrating hard enough, you’d be able to control the car. Didn’t work. Anyway, the point is that when you give the kids control of the source code, there’s <strong>no telling what will happen.</strong></p>


	<p>CouchDB’s replication facility has the potential to bring an explosion in innovation, as kids realize that they can hack and share the apps they use everyday. And duh, if you wanna be with it, you gotta keep up with what the kids are doing. ;) But seriously, the freedom we’ll see when people control their data, <em>and the applications they use to access it</em> is what keeps me up at night working on this.</p>


	<p>To participate in this Cambrian explosion you’ll be required to write your application by new rules. At first blush, pure CouchDB apps follow more restrictive constraints than even Google App Engine. However, I’ll argue that pure CouchDB apps can offer more room for <em>innovation</em>. This is because with a CouchDB app, you control the whole stack from root to fruit, and can deploy your applications on your own terms, from small scale in-house use to datacenter-level distributed systems.</p>


	<p>CouchDB already offers a built in <span class="caps">HTTP</span> server with attachment support and file uploads, as well as a rich set of APIs for storing and retrieving <span class="caps">JSON</span> records. By taking advantage of these characteristics pure-CouchDB applications can reach near parity with traditional server-heavy approaches. Notable exceptions include the ability to render dynamic text that isn’t <span class="caps">JSON</span>, or return results that require multiple queries against CouchDB.</p>


	<p>With the recent addition of _external support to CouchDB, now it is possible to craft dynamic <span class="caps">XML</span> responses (or anything else you can do from a JavaScript function) directly from CouchDB’s Spidermonkey script runner. In this article I’ll show some code that renders a CouchDB view as an Atom feed. Everything’s still very rough, but I’m encouraging people to hack on it and share. There’s a framework (or maybe a whole new way of working) emerging, and I want you to be a part of it.</p>


	<h2>What does a Pure CouchDB app look like?</h2>


	<p>I assume you already know about CouchDB’s database capabilities. To refresh: it’s a RESTy document store with incremental map reduce queries. The documents are <span class="caps">JSON</span> and the map reduce queries are written in JavaScript, or your language of choice, via a stdio socket that speaks a simple <span class="caps">JSON</span> protocol.</p>


	<p>Among CouchDB’s various documents, are those who’s _id starts with “_design/”. These documents contain the map reduce views, and according to Damien Katz, they should correspond 1:1 with the applications that run across a dataset. One application equals one design document.</p>


	<p>The example application in this post (and the script I’ve written to bootstrap it into CouchDB from the filesystem) is designed around this principle of one design document per application. I’m especially keen on the innovation that we’ll see when people start to write distinct and competing applications, that run across the same dataset.</p>


	<p>CouchDB documents can hold attachments, which are served up as the mime/type they were stored with. This makes it easy to store and serve <span class="caps">HTML</span>, CSS, Javascript, and even image files directly from CouchDB. By attaching a few <span class="caps">HTML</span> files and some JavaScript behavior to the design document, you can have a working blog, as I showed in the demo portion of <a href="http://www.vimeo.com/1992869">my Arc90 talk.</a></p>


	<p><img alt="" src="http://img.skitch.com/20081031-e77j61261e85g833nynd7de57m.png"/></p>


	<p>As a proof of concept, look no further than CouchDB’s built-in administrative interface. Futon, as it’s called, is just a collection of <span class="caps">HTML</span>, CSS, and Javascript files, and it is a fully functional database browser and <span class="caps">JSON</span> document editor, as well as the runner for CouchDB’s functional test suite. The test suite is written in Javascript and runs from the browser. What else could more strongly indicate that Ajax and CouchDB go hand in hand?</p>


	<p>JavaScript, static <span class="caps">HTML</span>, and CouchDB doesn’t buy you Atom or <span class="caps">RSS</span> feeds, however. And who’d seriously create blogging software without feeds? The _external server system to the rescue! Basically, CouchDB parses and forwards <span class="caps">HTTP</span> requests as <span class="caps">JSON</span> object to an external script. The external script can then process the <span class="caps">JSON</span>, make additional queries, and return whatever response it chooses, including redirects, <span class="caps">HTTP</span> status codes, plain <span class="caps">HTML</span>, JSON, or other content types.</p>


	<p><span class="caps">IMHO</span>, building raw Ajax + <span class="caps">JSON</span> apps is the fastest, simplest way to get a new idea in front of other people. I’ve done it a few times in various contexts. Grabb.it is just some Ajax on top of a <span class="caps">JSON API</span> (hosted on Rails and PostgreSQL). Grabb.it had to be Ajax-heavy, because changing pages would make the music stop. TracksPress (Grabb.it’s new skunkworks product) has a pay area, which is just Ajax on top of a Merb/CouchDB app. For me, pure Ajax applications have a winning track record.</p>


	<p>An Ajax app is simple: just get a shell of an <span class="caps">HTML</span> page up, throw on a little <span class="caps">CSS</span> and some jQuery, and you’re up and running. Back that with the power of CouchDB and suddenly you’re within striking distance of a real web app. Add CouchDB’s  `_external` handler and you can do anything another service would do, from rendering rss feeds to dropping an upload into a processing queue.</p>


	<h2>Still on the Edge (installing)</h2>


	<p>Installing <a href="http://github.com/jchris/couchdb-example-blog">couchdb-example-blog</a> isn’t nearly as easy as it should be. First of all couchapp, the installer script, requires Ruby, the CouchRest gem, and all of it’s dependencies. I’m considering porting couchapp to a leaner environment for convenience.</p>


	<p>Secondly, couchdb-example-blog requires a <a href="http://github.com/jchris/couchdb/tree/action2">non-standard branch of CouchDB itself.</a> This should be simplified in the future. The CouchDB team still needs to decide on a build process for plugins. The <a href="http://github.com/davisp/couchdb/tree/external2">_external</a> process manager I’ve been helping <a href="http://github.com/davisp">davisp</a> with, which powers action servers, as well as the Full Text Search interface, may make a model plugin, although it may end up included by default.</p>


	<p>For detailed installation directions, see <a href="http://github.com/jchris/couchdb-example-blog/tree/master/README.txt">the couchdb-example-blog <span class="caps">README</span></a> and it will step you through everything.</p>


	<h2>No Joke (Security Model)</h2>


	<p>CouchDB <em>will have</em> a comprehensive security and data validation module. The work may have already begun. It looks like <a href="http://damienkatz.net/">Damien</a> is targeting this as a 1.0 feature. The upshot is that the security model is not yet available, but <a href="http://incubator.apache.org/couchdb/docs/overview.html">there is a description of it.</a> (see Security and Validation)</p>


	<p>Basically, any changes, such as document <span class="caps">POST</span>, PUT and <span class="caps">DELETE</span>, are validated by a JavaScript function, which is supplied the currently saved version of the document, the proposed version of the document, and some information about the request (including the user or other authentication parameters.) The function may return false to indicate an invalid operation, or true to let the operation proceed. There’s talk of extending the specification to allow validation functions to set values on the to-be-saved document, like timestamps or user information. With such this security model, it is possible to implement author-only saves, data format checks, and probably most of what application programmers require.</p>


	<h2><span class="caps">E4X</span>: ECMAScript for <span class="caps">XML</span></h2>


	<p><img alt="" src="http://img.skitch.com/20081031-fu5px898gh3fsmbrypfuy33wss.png"/></p>


	<p>Spidermonkey includes the <span class="caps">E4X</span> extensions, which give it the ability to manipulate <span class="caps">XML</span> with a native <span class="caps">API</span>. You get to use JavaScript “dot notation” to mess with <span class="caps">XML</span>. Most articles and tutorials out there are tailored towards parsing <span class="caps">XML</span>. That may be important to some folks (if so check out the links in the previous sentence.)</p>


	<p>Instead I’ll show <a href="http://github.com/jchris/couchdb-example-blog/tree/master/actions/atom-posts.js">how I generated an Atom feed using Spidermonkey’s JavaScript interpreter.</a> It’s deceptively simple. I’m sure there are better ways to do this with <span class="caps">E4X</span>, but hey, this one’s not that bad.</p>


	<p>First we load the design document from CouchDB, and use it’s blog attribute to fill out some template values in the <span class="caps">XML</span> feed header.</p>


<code><pre>  var blog = db.open('_design/couchdb-example-blog').blog;

  var feed = &lt;feed xmlns="http://www.w3.org/2005/Atom"&gt;
    &lt;title&gt;{blog.title}&lt;/title&gt;
    &lt;link href={blog.url}/&gt;
    &lt;updated&gt;2003-12-13T18:30:02Z&lt;/updated&gt;
    &lt;author&gt;
      &lt;name&gt;{blog.author.name}&lt;/name&gt;
    &lt;/author&gt;
    &lt;id&gt;{blog.url}&lt;/id&gt;
  &lt;/feed&gt;
</pre></code>

	<p>If we were to call `feed.toXMLString()` now we’d get just what it seems like we’d get, with everything all escaped and quoted correctly. We still need to add the entries to the feed, so we’ll fetch a view and iterate over its posts, copying them to the <span class="caps">XML</span>. Check out how easy the dot notation makes this. (Note that it looks like attribute access, but really it’s a big nasty <span class="caps">XML</span> operation, so don’t do more than you need.)</p>


<code><pre>  var view = db.view('couchdb-example-blog/recent',{count:10,descending:true});

  for (r in view.rows) {
    var row = view.rows[r];
    var post = row.value;
    var entry = &lt;entry/&gt;;
    entry.id = blog.url + '/' + row.id;
    entry.title = post.title;
    entry.updated = post.date;
    entry.content = post.body;
    feed.entry += entry;    
  }

  return {body: feed.toXMLString()};
</pre></code>

	<p>Now our example blog has a feed, so it’s a real blog. Of course it’s barely a real blog, but at this point features like <a href="http://gravatar.com">Gravatar</a> integration and comment moderation are just window dressing.</p>


	<h2>Data Portability</h2>


	<p>Why does it matter that CouchDB can serve standalone apps? Why should developers go through the trouble to learn a new paradigm?</p>


	<p>I think any platform that gets out of the way enough to let you build Ajax apps with only the bare minimum server logic is a win in terms of developer productivity. But if you are hesitant on that front, consider the potential for portability.</p>


	<p>When all developers need to do, to run their own instance of an application, is install CouchDB, suddenly we’re talking about a platform even more simple than <span class="caps">PHP</span> plus MySQL, which has become the gold standard for ease of installation. Imagine if the process for installing a new <span class="caps">CMS</span>, or a new ticket tracker, or any other browser based application was a simple as replicating a _design document from the application’s root repository.</p>


	<p>What’s more, pure-CouchDB apps don’t care if they are hosted on a local laptop, on a school or company intranet, or open on the web for all to use. The same code base can work in all those contexts, and the same set of data can be replicated across them. One of CouchDB’s sweet-spots is offline replication. This means you could host an application at a school, allow students to replicate it to their laptops, work on it at home, and turn their work in by replicating back when they return to school. Data can be distributed without complex access controls, as would be required if the students accessed the school’s network from the public internet.</p>


	<p>I look forward to seeing some of the prototypical Web 2.0 use cases migrate to this user-controlled future. What will photo-sharing look like when you can send your photo album, along with its user-modifiable browsing application, directly to friends? The web has shown that the power to view source is a catalyst for learning and innovation. With CouchDB apps, view-source exposes the whole application. I’d <em>really</em> like to see some public-data projects like <a href="http://public.resource.org/">Public.Resource.Org</a> and <a href="http://www.sunlightfoundation.com/">The Sunlight Foundation</a> experiment with user-owned applicatios.</p>


	<h2>Low-Hanging Fruit</h2>


	<p>Here are just a few ideas for standalone CouchDB application that I’ve come up with. I’d love to see any of them shared around, preferable under a free-license.</p>


	<p>Feed Reader: CouchDB should be able to provide a user experience similar to Google’s Reader. Using their <span class="caps">API</span> you could probably even interact with your friend’s shared items like you’re used to. A nice point about action server modules, is that they can be easily generalized – eg a function that’s used by one app to fetch feeds can be reused in another to power an image downloader or even a web spider.</p>


	<p>Ticket Tracker: Imagine Trac as a distributed Ajax application. Now remove all the features you never use. Working offline has proven productive in the mass exodus to git and other dvcs. Managing project information with offline clients may prove to have some of the same efficiencies.</p>


	<p>Wikis: The appeal of a CouchDB wiki is that it’d be easy to keep relatively private.  A prototypical use case is in the classroom: a group wiki which students are able to edit at home even without network access.</p>


	<h2>The Future</h2>


	<p>This essay has been largely speculative. However, it is backed up by running code. I consider it a call to arms. If you’re inspired by CouchDB, or by the potential freedom that we’ll win by open-sourcing all the web apps, I encourage you to start working now.</p>


	<p>We could really use someone to package CouchDB as a browser plugin. Our license is compatible with the Gears license—all we need is someone to tackle the build.</p>


	<p>Also, write applications, share applications, and fork them. I hope to be running this blog from CouchDB as soon as the security features have been implemented. What else is ready for prime time?</p></div>
    </summary>
    <updated>2008-11-01T02:25:33Z</updated>
    <source>
      <id>http://jchris.mfdz.com/posts</id>
      <author>
        <name>Chris Anderson</name>
      </author>
      <link href="http://jchris.mfdz.com/posts" rel="alternate" type="text/html"/>
      <link href="http://jchris.mfdz.com/xml/rss20/feed.xml" rel="self" type="application/rss+xml"/>
      <title>Daytime Running Lights : Coding</title>
      <updated>2008-11-21T16:40:11Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.501</id>
    <link href="http://damienkatz.net/2008/10/post.html" rel="alternate" type="text/html"/>
    <title>Relax with CouchDB</title>
    <summary>O'Reilly Media is publishing an Apache CouchDB book! How cool is that? I was hoping they'd put David Hasselhoff on the cover, for good luck and of course good looks. But they said it's always an animal on the covers....</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>O'Reilly Media is <a href="http://books.couchdb.org/relax/">publishing an Apache CouchDB book</a>! How cool is that?</p>

<p>I was hoping they'd put David Hasselhoff on the cover, for good luck and of course good looks. But they said it's always an animal on the covers. Oh well.</p></div>
    </content>
    <updated>2008-10-28T23:13:33Z</updated>
    <published>2008-10-28T23:02:15Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://jan.prima.de/~jan/plok/archives/159-guid.html</id>
    <link href="http://jan.prima.de/~jan/plok/archives/159-Announcing-Relax-with-CouchDB-by-OReilly.html" rel="alternate" type="text/html"/>
    <title>Announcing "Relax with CouchDB" by O'Reilly</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I am happy to announce that <a href="http://bytesexual.org/nslater">Noah Slater</a>, <a href="http://jchris.mfdz.com/">J. Chris Anderson</a> and I are writing <a href="http://books.couchdb.org/relax/">“Relax with CouchDB”</a> for <a href="http://oreilly.com/">O’Reilly</a>.</p>

<blockquote>
  <p>The book is designed to guide you gently through using CouchDB with clear but practical scenarios. We progressively showcase key features, starting with simple document CRUD, working through to advanced MapReduce, and culminate with deployment tuning for performance and reliability.</p>
</blockquote>

<p>Writing is hard, but Noah and Chris have already proven to be the best co-authors I could have wished for.</p>

<p>The kicker, for me, is that we will be releasing the book under a <a href="http://creativecommons.org/licenses/by/3.0/">free license (CCby03)</a> .</p>

<p>We’ve set up a <a href="http://groups.google.com/group/couchdb-relax">Google Group for feedback</a> where you can tell us what you would like to read. We will be releasing chapters as we write them (open license FTW) and we’d like to get your insights on how we are doing and what we are missing.  <a href="http://groups.google.com/group/couchdb-relax">Sign up now</a>, thanks a lot!</p></div>
    </content>
    <updated>2008-10-27T13:48:15Z</updated>
    <category term="couchdb"/>
    <category term="Nerdery"/>
    <category term="PHP"/>
    <author>
      <name>Jan</name>
      <email>jan@apache.org</email>
    </author>
    <source>
      <id>http://jan.prima.de/~jan/plok/</id>
      <logo>http://jan.prima.de/~jan/plok/templates/default/img/s9y_banner_small.png</logo>
      <link href="http://jan.prima.de/~jan/plok/" rel="alternate" type="text/html"/>
      <link href="http://jan.prima.de/plok/feeds/categories/9-CouchDB.rss" rel="self" type="application/rss+xml"/>
      <title>plok - couchdb</title>
      <updated>2008-11-15T10:40:04Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://jan.prima.de/~jan/plok/archives/158-guid.html</id>
    <link href="http://jan.prima.de/~jan/plok/archives/158-International-PHP-Conference-2008.html" rel="alternate" type="text/html"/>
    <title>International PHP Conference 2008</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p><a href="http://kore-nordmann.de/blog.html">My friend Kore</a> and I will  be <a href="http://it-republik.de/konferenzen/ext_scripts/php/sessions-popup.php?module=ipc&amp;id=8636">speaking</a> about “Document based databases: CouchDB” at the <a href="http://it-republik.de/php/phpconference/">International PHP Conference</a> in Mainz this week. </p>

<p>Join us for the red-eye session at 08:30 on Thursday. Yes, this is the morning after the conference party. (Dear Orga, nice job of letting us know that you are not really interested in our topic.) We’re trying to make up for the early hour by giving an extra fun talk.</p>

<p>I’m excited to go and meet all of you. Make sure to <a href="http://twitter.com/janl">ping me on Twitter</a> or grab me in the hallway.</p></div>
    </content>
    <updated>2008-10-27T13:36:18Z</updated>
    <category term="couchdb"/>
    <category term="Nerdery"/>
    <category term="PHP"/>
    <author>
      <name>Jan</name>
      <email>jan@apache.org</email>
    </author>
    <source>
      <id>http://jan.prima.de/~jan/plok/</id>
      <logo>http://jan.prima.de/~jan/plok/templates/default/img/s9y_banner_small.png</logo>
      <link href="http://jan.prima.de/~jan/plok/" rel="alternate" type="text/html"/>
      <link href="http://jan.prima.de/plok/feeds/categories/9-CouchDB.rss" rel="self" type="application/rss+xml"/>
      <title>plok - couchdb</title>
      <updated>2008-11-15T10:40:04Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://upstream-berlin.com/?p=346</id>
    <link href="http://upstream-berlin.com/2008/10/27/couch-potato-unleashed-a-couchdb-persistence-layer-in-ruby/" rel="alternate" type="text/html"/>
    <title>Couch Potato unleashed - a couchdb persistence layer in ruby (updated)</title>
    <summary>Update: the gem is now available, see the installation instructions below.
After several weeks of incubating on my computer it’s finally time to get real: I have just open sourced Couch Potato under the MIT license. You can get Couch Potato on github now. For an introduction to CouchDB and ruby please read my previous blog [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p><strong>Update:</strong> the gem is now available, see the installation instructions below.</p>
<p>After several weeks of incubating on my computer it’s finally time to get real: I have just open sourced Couch Potato under the MIT license. You can <a href="http://github.com/langalex/couch_potato">get Couch Potato on github</a> now. For an introduction to CouchDB and ruby please read my previous blog post <a href="http://upstream-berlin.com/2008/09/25/a-couchdb-primer-for-an-activerecord-mindset/">A CouchDB primer for an ActiveRecord mindset</a>. The following is a very short introduction into using Couch Potato. If you want to know more you can start with the <a href="http://github.com/langalex/couch_potato/tree/master/README.textile">README</a>.</p>
<p>The goal of Couch Potato is to create a migration path for users of ActiveRecord and other object relational mappers to port their applications to CouchDB. It therefore offers a basic set of the functionality provided by most ORMs and adds functionality unique to CouchDB on top.</p>
<h3>Installation</h3>
<p>Couch Potato is available as a gem from http://gems.github.com, so you can just do </p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">$ sudo gem source --add http://gems.github.com # if you haven't alread
$ sudo gem install langalex-couch_potato

$ irb
&gt;&gt; require 'rubygems'
&gt;&gt; gem 'couch_potato'
&gt;&gt; require 'couch_potato'
&gt;&gt; CouchPotato::Config.database_name = 'name of the db'
</textarea>
<p>Alternatively you can  download the sources from github. If you are using rails just copy the files into vendor/plugins, create a RAILS_ROOT/config/couchdb.yml file (see the README for the format) and you are ready to go. For other applications you will have to require the lib/couch_potato.rb file and then set the database name by calling <code>CouchPotato::Config.database_name = 'name of the db'</code>.</p>
<p>As Couch Potato is still very young you can expect its feature set to grow quite a bit in the near future. What you can download now is the very core together with a few features giving you a glimpse of what is about to come:</p>
<h3>Persistence</h3>
<p>Create a new class and make its instances persistable by including the Persistence module. As there is no schema in a CouchDB you have to declare the properties you want to persist:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">class User
  include CouchPotato::Persistence
  
  property :name
end
</textarea>
<p>Now you can save your objects:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">user = User.new :name =&gt; 'joe'
user.save # or save!
</textarea>
<p>Properties:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">user.name # =&gt; 'joe'
user.name = {:first =&gt; ['joe', 'joey'], :last =&gt; 'doe', :middle =&gt; 'J'} # you can set any ruby object that responds_to :to_json
user._id # =&gt; "02097f33a0046123f1ebc0ebb6937269"
user.created_at # =&gt; Fri Oct 24 19:05:54 +0200 2008
</textarea>
<p>You can of course also retrieve your instance:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">User.get "02097f33a0046123f1ebc0ebb6937269" # =&gt; &lt; #User 0x3075&gt;
</textarea>
<h3>Associations</h3>
<p>As of now has_many and belongs_to are supported. By default the associated objects are stored in separate documents linked via foreign keys just like in relational databases.</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">class User
  has_many :addresses, :dependent =&gt; :destroy
end
  
class Address
  belongs_to :user
  property :street
end
  
user = User.new
user.addresses.build :street =&gt; 'potato way'
user.addresses.first # =&gt; &lt; #Address 0x987&gt;
user.addresses.create! # raises an exception as street is blank
user.addresses.first.user == user # =&gt; true
</textarea>
<p>When saving an object all associated objects are automatically saved as well. All these save operations are sent to CouchDB in one operation which means the whole process is atomic across all objects saved, plus only one database roundtrip is required making it much faster.</p>
<p>As CouchDB can not only store flat structures you also store associations inline:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">class User
  has_many :addresses, :stored =&gt; :inline
end
</textarea>
<p>This will store the addresses of the user as an array within your CouchDB document.</p>
<p><span id="more-346"/></p>
<h3>Callbacks</h3>
<p>Couch Potato supports the usual lifecycle callbacks known from ActiveRecord:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">class User
  include CouchPotato::Persistence
  
  before_create :do_something_before_create
  after_update :do_something_else
end
</textarea>
<h3>Versioning</h3>
<p>Couch Potato supports versioning your objects, very similar to the popular acts_as_versioned plugin for ActiveRecord. To use it include the module:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">class Document
  include CouchPotato::Persistence
  include CouchPotato::Versioning
end
</textarea>
<p>After that your object will have a version that gets incremented on each save.</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">doc = Document.create
doc.version # =&gt; 1
doc.save
doc.version # =&gt; 2
</textarea>
<p>You can access the older versions via the versions method.</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">doc.versions.first.version # =&gt; 1
</textarea>
<p>When passing a version number the version method will only return that version:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">doc.versions(1).version # =&gt; 1
</textarea>
<h3>Ordered Lists</h3>
<p>Couch Potato supports ordered lists for has_many relationships (with the :stored =&gt; :separately option only), very similar to the popular acts_as_list plugin for ActiveRecord. To use it include the module:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">class PersistenArray
  include CouchPotato::Persistence
  has_many :items
end
  
class Item
  include CouchPotato::Ordering
  belongs_to :persistent_array
  set_ordering_scope :persistent_array_id
end
  
array = PersistenArray.new
item1 = array.items.create!
item1.position # =&gt; 1
item2 = array.items.create!
item2.position # =&gt; 2
</textarea>
<p>You can move items up and down simply by changing the position:</p>
<textarea class="ruby:showcolumns" cols="60" name="code" rows="10">item2.position = 1
item2.save!
item1.position # =&gt; 2
</textarea>
<h3>Conclusion</h3>
<p>Couch Potato is very young and it’s open source, so if you find any bugs (you most definitely will) please go to the <a href="http://upstream.lighthouseapp.com/projects/18819-couch-potato">bug tracker</a> and file a ticket. If you want to contribute please create a fork on github. If you have ideas for improvements please email me or comment on this post.</p></div>
    </content>
    <updated>2008-10-27T09:50:40Z</updated>
    <category term="Uncategorized"/>
    <category term="couchdb"/>
    <category term="couchpotato"/>
    <category term="persistence"/>
    <category term="ruby"/>
    <author>
      <name>Alexander Lang</name>
    </author>
    <source>
      <id>http://upstream-berlin.com</id>
      <link href="http://upstream-berlin.com/feed/?tag=couchdb" rel="self" type="application/atom+xml"/>
      <link href="http://upstream-berlin.com" rel="alternate" type="text/html"/>
      <title>upstream agile - software » couchdb</title>
      <updated>2008-11-13T16:10:06Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://jchris.mfdz.com/posts/127</id>
    <link href="http://jchris.mfdz.com/posts/127" rel="alternate" type="text/html"/>
    <title>Relax with CouchDB</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I’m very pleased to announce that I’m lucky enough to be co-authoring the forthcoming <a href="http://oreilly.com/">O’Reilly</a> book: <a href="http://books.couchdb.org/relax/"><em>Relax With CouchDB</em></a></p>


	<p>My co-authors are <a href="http://jan.prima.de/">Jan Lehnardt</a> and <a href="http://bytesexual.org/nslater">Noah Slater</a>. They’ve already proven to be the right guys to write this book with.</p>


	<p>We’re releasing the book online under a <a href="http://creativecommons.org/licenses/by/3.0/">free license</a>, and we hope to integrate your feedback.</p>


	<p>CouchDB can be used in a lot of different ways, so ensuring that we’re covering the topics that you’re interested in is a top priority.</p>


	<p><a href="http://groups.google.com/group/couchdb-relax">There is a Google Group for feedback</a>—let us know what you’d like to see!</p>


	<p>We’ll be soliciting reader feedback as we develop the book and <span class="caps">API</span> documentation. The content is freely licensed, so we’ll make it available as we write. Expect to see a few chapters and a some <span class="caps">API</span> docs up by the end of the year.</p>


	<p>Writing a book takes time.</p></div>
    </summary>
    <updated>2008-10-27T05:08:41Z</updated>
    <source>
      <id>http://jchris.mfdz.com/posts</id>
      <author>
        <name>Chris Anderson</name>
      </author>
      <link href="http://jchris.mfdz.com/posts" rel="alternate" type="text/html"/>
      <link href="http://jchris.mfdz.com/xml/rss20/feed.xml" rel="self" type="application/rss+xml"/>
      <title>Daytime Running Lights : Coding</title>
      <updated>2008-11-21T16:40:11Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo/</id>
    <link href="http://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo" rel="alternate" type="text/html"/>
    <title>GeoCouch: Geospatial queries with CouchDB</title>
    <summary>[...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>After almost six months of silence I finally managed to get a prototype done
(thanks <a href="http://jan.prima.de/~jan/">Jan</a> for keeping me motivated).
</p>

<h3>What do you get?</h3>
<p>You get some code to play around with, to get a slight idea of how such a
geospatial extension for <a href="http://couchdb.org/">CouchDB</a> could look
like. The code base isn’t polished yet, but it’s good enough to get it out of
the door. The current version only supports one geometry type
(<code>POINT</code>), and one operation (a bounding box search).
</p>
<p>As CouchDB doesn’t allow an intersection of results gathered from an
external service, the result of the bounding box search will be plain text
document IDs and their coordinates.
</p>

<h3>How does it work?</h3>
<p>GeoCouch consists of two parts, the indexer and the query processor.
Both are connected through stdin/out with CouchDB.</p>

<h4>Indexer (geostore)</h4>
<p>In order to make the indexer understand which fields in the document contain
geometries, a special design document is needed. As soon as a database has such
a document, the database is <em>geo-enabled</em> and the indexer will store the
geometries in a spatial index, which is a
<a href="http://www.gaia-gis.it/spatialite/">SpatiaLite</a> database at the
moment.
</p>
<p>Everytime a database in CouchDB is altered (create, delete, update) the
indexer gets notified and will act accordingly to keep the spatial index
up to date with CouchDB.
</p>

<h4>Query processor (geoquery)</h4>
<p>To process queries with an external service is possible with
<a href="http://www.davispj.com/">Paul Joseph Davis’</a> excellent
<a href="http://github.com/davisp/couchdb/tree/external2">
external2 CouchDB branch</a>. Queries to CouchDB can get passed along to an
external service.
</p>
<p>At the moment the result is the output of this service, it’s plain text in
our case. In the future the external service will only return document IDs
which will be passed back to the view. The result will be an intersection of
document IDs of the view and the document IDs the external service returned.
</p>

<h3>How do I use it?</h3>
<p>When everything is installed correctly it’s quite easy to get started.</p>

<h4>Setting things up</h4>
<ul>
  <li>Create a new database named <code>geodata</code> (could be anything).</li>
  <li>Add a document named <code>myhome</code>, there you’ll store all the information
of your home including the coordinates. As we are only interested in a bounding
box search it’s enough to have a location:
      <pre><code>{
  "_id": "myhome",
  "_rev": "3358484250",
  "location": [ 151.208333, -33.869444 ]
}</code></pre>
  </li>
  <li>Add as many other documents like this, make sure all of them have a field
called <code>location</code> with the coordinates as array. As for the database,
the name of the field could be anything, but has to be the same in all
documents.
  </li>
  <li>Now we come to the interesting part, the special design view that
<em>geo-enables</em> the database. The document has to be named
“<code>_design/_geocouch</code>”. After creating it also needs some special fields and
will look like this:
    <p>
      </p><pre><code>{
  "_id": "_design/_geocouch",
  "_rev": "610069068",
  "srid": 4326,
  "loc": {
    "type": "POINT",
    "x": "location[0]",
    "y": "location[1]"
  }
}</code></pre>
    <p/>
    <p>The coordinate system that should be used is specified by an
<a href="http://en.wikipedia.org/wiki/SRID">SRID</a>. If you don’t know which
value to use for <code>srid</code>, use <code>4326</code>. It’s assumed that
all geometries in your document belong to the same coordinate system.
    </p>
    <p>The other field is the information where to find the geometry in the
documents. The name you choose will be used for the bounding box queries,
I’ve chosen <code>loc</code>. It defines the type (<code>POINT</code>), and
where to find the x/y coordinate (this will probably be changed to lat/lon in
the future).
    </p>
    <p>The way to specify where to find the field is comparable to XPath, but
much simpler. As JSON consists of nested dictionaries and arrays, you can get a
property within an array with the index (e.g. <code>location[0]</code> is the
first element in an Array called <code>location</code>). If it is a dictionary
you specify it separated by a dot (e.g. <code>location.x</code> is a property
named <code>x</code> within another one called <code>location</code>). It can
of course be nested much deeper, the path always starts at the root of the
document (e.g. <code>bike.stolen.found[0]</code>).
    </p>
  </li>
</ul>

<h4>Bounding box search</h4>
<p>And finally you can make a bounding box search. Simply browse a URL like
this one (this is a bounding box that encloses the whole world):
</p>
<p>
  </p><pre><code>http://localhost:5984/geodata/_external/geo?q={"geom":"loc","bbox":[-180,-90,180,90]}
</code></pre>
<p/>
<p>The expected result is:</p>
<p>
  </p><pre><code>myhome 151.208333 -33.869444</code></pre>
<p/>

<h3>Requirements</h3>
<p>You’d like to give it a try? Here is a list of the software and their versions
I used to get it work on my system, but others might work as well. GeoCouch
includes installation/configuration instructions.</p>
<ul>
  <li><a href="http://www.kernel.org/">Linux 2.6.26</a></li>
  <li><a href="http://www.python.org/">Python 2.5.2</a></li>
  <li><a href="http://code.google.com/p/apsw/&quot;">APSW - Another Python SQLite Wrapper 3.5.9-r2</a></li>
  <li><a href="http://www.gaia-gis.it/spatialite/">SpatiaLite 2.2</a></li>
  <li><a href="http://github.com/davisp/couchdb/tree/external2">
davisp’s external2 branch of CouchDB</a>
  </li>
</ul>

<h3>Download GeoCouch</h3>
<p>Get SpacialCouch now! It’s new, it’s free
(<a href="http://www.opensource.org/licenses/mit-license.php">MIT</a>
licensed).</p>
<ul>
  <li><a href="http://vmx.cx/blog/2008-10-26/geocouch-0.0.1.tar.bz2">
GeoCouch 0.0.1</a></li>
</ul>

<h3>What’s next?</h3>
<p>The current version is meant to play with, many things are not possible,
many things needs to be improved. But with the power of SpatiaLite (and the
underlying libraries) it shouldn’t be too hard.
</p>
<p>Therefore I hope this will only be start and will end up in a discussion
on what should be done, what other things might be possible. I’d love to
hear your use cases for a geospatially enabled CouchDB.</p></div>
    </content>
    <updated>2008-10-26T13:30:12Z</updated>
    <category term="en"/>
    <category term="CouchDB"/>
    <category term="Python"/>
    <category term="geo"/>
    <author>
      <name>Volker Mische</name>
    </author>
    <source>
      <id>http://vmx.cx/cgi-bin/blog/index.cgi</id>
      <link href="http://vmx.cx/cgi-bin/blog/index.cgi" rel="alternate" type="text/html"/>
      <link href="http://vmx.cx/cgi-bin/blog/index.cgi/category/CouchDB/feed/" rel="self" type="application/rss+xml"/>
      <subtitle>Blog of Volker Mische</subtitle>
      <title>vmx: CouchDB</title>
      <updated>2008-10-26T13:30:12Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.500</id>
    <link href="http://damienkatz.net/2008/10/exploring_the_design_couchdb.html" rel="alternate" type="text/html"/>
    <title>Exploring the Design of CouchDB</title>
    <summary>I've spent some time chatting about CouchDB with Ricky Ho from Adobe Systems , and he's put together a really great post detailing a lot of the high level design of CouchDB: CouchDB Implementation I highly recommend reading it if...</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>I've spent some time chatting about CouchDB with <a href="http://horicky.blogspot.com/">Ricky Ho</a> from Adobe Systems , and he's put together a really great post detailing a lot of the high level design of CouchDB: <a href="http://horicky.blogspot.com/2008/10/couchdb-implementation.html">CouchDB Implementation</a></p>

<p>I highly recommend reading it if you want to know more about the inner workings of CouchDB.</p></div>
    </content>
    <updated>2008-10-24T04:36:40Z</updated>
    <published>2008-10-23T21:20:41Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:www.davispj.com,2008-10-19:1224452182</id>
    <link href="http://www.davispj.com/couchdb/views/indexing/protocol.html" rel="alternate" type="text/html"/>
    <title>CouchDB View Index Protocol</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1><a href="http://www.davispj.com/couchdb/views/indexing/protocol">CouchDB View Index Protocol</a></h1>
<h3>See also: <a href="http://www.davispj.com/couchdb/views/indexing/idea">CouchDB View Indexing</a></h3>
<p>A quick document outlining the line protocol for the couchdb-view-index patch I wrote yesterday.</p>
<p>There are four types of interactions:</p>
<ol>
	<li>Reset – Sent when the external process has been grabbed for new processing</li>
	<li>Index – Sent with view rows to add and delete from the index</li>
	<li>Delete – Sent when the view has been reset and things need to start over</li>
	<li>Query – Sent with url query string parameters to query the view.</li>
</ol>
<h2>Note</h2>
<p>This is a line protocol. I have formatted everything here, but in real life all messages and responses (except the query response) must be a single line terminated by a newline character. The query response is dicussed below.</p>
<h2>Reset</h2>
<h3>Message</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> {<span class="String"><span class="String">"</span>action<span class="String">"</span></span>: <span class="String"><span class="String">"</span>reset<span class="String">"</span></span>}
</pre></div>
<h3>Response</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Constant">true</span>
</pre></div>
<h2>Index</h2>
<h3>Message</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> {
<span class="line-numbers">   2 </span>     <span class="String"><span class="String">"</span>action<span class="String">"</span></span>: <span class="String"><span class="String">"</span>index<span class="String">"</span></span>,
<span class="line-numbers">   3 </span>     <span class="String"><span class="String">"</span>db<span class="String">"</span></span>: <span class="String"><span class="String">"</span>db_name<span class="String">"</span></span>,
<span class="line-numbers">   4 </span>     <span class="String"><span class="String">"</span>group<span class="String">"</span></span>: <span class="String"><span class="String">"</span>_design/foo<span class="String">"</span></span>,
<span class="line-numbers">   5 </span>     <span class="String"><span class="String">"</span>views<span class="String">"</span></span>: [<span class="String"><span class="String">"</span>bar<span class="String">"</span></span>, <span class="String"><span class="String">"</span>baz<span class="String">"</span></span>],
<span class="line-numbers">   6 </span>     <span class="String"><span class="String">"</span>current_seq<span class="String">"</span></span>: <span class="Constant">508</span>,
<span class="line-numbers">   7 </span>     <span class="String"><span class="String">"</span>new_seq<span class="String">"</span></span>: <span class="Constant">602</span>,
<span class="line-numbers">   8 </span>     <span class="String"><span class="String">"</span>insert<span class="String">"</span></span>: [
<span class="line-numbers">   9 </span>         {<span class="String"><span class="String">"</span>docid<span class="String">"</span></span>: <span class="String"><span class="String">"</span>a<span class="String">"</span></span>, <span class="String"><span class="String">"</span>key<span class="String">"</span></span>: <span class="Constant">1</span>, <span class="String"><span class="String">"</span>value<span class="String">"</span></span>: <span class="String"><span class="String">"</span>data here<span class="String">"</span></span>},
<span class="line-numbers">  10 </span>         {<span class="String"><span class="String">"</span>docid<span class="String">"</span></span>: <span class="String"><span class="String">"</span>b<span class="String">"</span></span>, <span class="String"><span class="String">"</span>key<span class="String">"</span></span>: <span class="Constant">2</span>, <span class="String"><span class="String">"</span>value<span class="String">"</span></span>: <span class="Constant">null</span>}
<span class="line-numbers">  11 </span>     ],
<span class="line-numbers">  12 </span>     <span class="String"><span class="String">"</span>remove<span class="String">"</span></span>: [{<span class="String"><span class="String">"</span>docid<span class="String">"</span></span>: <span class="String"><span class="String">"</span>c<span class="String">"</span></span>, <span class="String"><span class="String">"</span>key<span class="String">"</span></span>: <span class="Constant">3</span>}]
<span class="line-numbers">  13 </span> }
</pre></div>
<p>When implementing an indexer you should process the `remove` documents first to match the semantics of CouchDB’s internal system.</p>
<h3>Response</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Constant">true</span>
</pre></div>
<h2>Delete</h2>
<h3>Message</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> {
<span class="line-numbers">   2 </span>     <span class="String"><span class="String">"</span>action<span class="String">"</span></span>: <span class="String"><span class="String">"</span>delete<span class="String">"</span></span>,
<span class="line-numbers">   3 </span>     <span class="String"><span class="String">"</span>db<span class="String">"</span></span>: <span class="String"><span class="String">"</span>foo<span class="String">"</span></span>,
<span class="line-numbers">   4 </span>     <span class="String"><span class="String">"</span>group<span class="String">"</span></span>: <span class="String"><span class="String">"</span>_design/bar<span class="String">"</span></span>,
<span class="line-numbers">   5 </span>     <span class="String"><span class="String">"</span>current_seq<span class="String">"</span></span>: <span class="Constant">6</span>
<span class="line-numbers">   6 </span> }
</pre></div>
<h3>Response</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Constant">true</span>
</pre></div>
<h2>Query</h2>
<h3>Message</h3>
<p>Given a url of something like:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> curl <span class="String"><span class="String">'</span>http://127.0.0.1:5984/zing/_index/idx_type/foo/bar?q="my query"&amp;count=19&amp;skip=10<span class="String">'</span></span>
</pre></div>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> {
<span class="line-numbers">   2 </span>     <span class="String"><span class="String">"</span>action<span class="String">"</span></span>: <span class="String"><span class="String">"</span>query<span class="String">"</span></span>,
<span class="line-numbers">   3 </span>     <span class="String"><span class="String">"</span>db<span class="String">"</span></span>: <span class="String"><span class="String">"</span>zing<span class="String">"</span></span>,
<span class="line-numbers">   4 </span>     <span class="String"><span class="String">"</span>group<span class="String">"</span></span>: <span class="String"><span class="String">"</span>_design/foo<span class="String">"</span></span>,
<span class="line-numbers">   5 </span>     <span class="String"><span class="String">"</span>view<span class="String">"</span></span>: <span class="String"><span class="String">"</span>bar<span class="String">"</span></span>,
<span class="line-numbers">   6 </span>     <span class="String"><span class="String">"</span>query<span class="String">"</span></span>: {
<span class="line-numbers">   7 </span>         <span class="String"><span class="String">"</span>q<span class="String">"</span></span>: <span class="String"><span class="String">"</span>my query<span class="String">"</span></span>,
<span class="line-numbers">   8 </span>         <span class="String"><span class="String">"</span>count<span class="String">"</span></span>: <span class="Constant">19</span>,
<span class="line-numbers">   9 </span>         <span class="String"><span class="String">"</span>skip<span class="String">"</span></span>: <span class="Constant">10</span>
<span class="line-numbers">  10 </span>     }
<span class="line-numbers">  11 </span> }
</pre></div>
<p>Anything passed as a <span class="caps">URL</span> parameter will be sent to the index process. You must ensure that all query string parameters are valid <span class="caps">JSON</span> that can be decoded by CouchDB’s <span class="caps">JSON</span> module.</p>
<h3>Response</h3>
<p>This is where things get complicated. The query response comes in three stages:</p>
<ol>
	<li>Initialization</li>
	<li>Streaming Results</li>
	<li>Termination</li>
</ol>
<h4><strong>Initialization</strong></h4>
<p>This should initialize the query and try and detect any forseeable errors.</p>
<p>Signal that all is well:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Constant">true</span>    
</pre></div>
<p>Or that all is <strong>not</strong> well:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> [<span class="Constant">404</span>, <span class="String"><span class="String">"</span>missing<span class="String">"</span></span>, <span class="String"><span class="String">"</span>not_found<span class="String">"</span></span>]
</pre></div>
<h4><strong>Streaming Results</strong></h4>
<p>You can stream any free-form json that you want to end up at the client. You should probably support a minimum of the expected view output:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> {<span class="String"><span class="String">"</span>total_rows<span class="String">"</span></span>: <span class="Constant">10</span>, <span class="String"><span class="String">"</span>offset<span class="String">"</span></span>: <span class="Constant">8</span>, <span class="String"><span class="String">"</span>rows<span class="String">"</span></span>: [
<span class="line-numbers">   2 </span> {<span class="String"><span class="String">"</span>id<span class="String">"</span></span>: <span class="String"><span class="String">"</span>h_docid<span class="String">"</span></span>, <span class="String"><span class="String">"</span>key<span class="String">"</span></span>: <span class="Constant">8</span>, <span class="String"><span class="String">"</span>value<span class="String">"</span></span>: <span class="String"><span class="String">"</span>foo<span class="String">"</span></span>},
<span class="line-numbers">   3 </span> {<span class="String"><span class="String">"</span>id<span class="String">"</span></span>: <span class="String"><span class="String">"</span>i_docid<span class="String">"</span></span>, <span class="String"><span class="String">"</span>key<span class="String">"</span></span>: <span class="Constant">9</span>, <span class="String"><span class="String">"</span>value<span class="String">"</span></span>: <span class="String"><span class="String">"</span>bar<span class="String">"</span></span>}
<span class="line-numbers">   4 </span> {<span class="String"><span class="String">"</span>id<span class="String">"</span></span>: <span class="String"><span class="String">"</span>j_docid<span class="String">"</span></span>, <span class="String"><span class="String">"</span>key<span class="String">"</span></span>: <span class="Constant">10</span>, <span class="String"><span class="String">"</span>value<span class="String">"</span></span>: <span class="String"><span class="String">"</span>baz<span class="String">"</span></span>}
<span class="line-numbers">   5 </span> ]}
</pre></div>
<h4><strong>Termination</strong></h4>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> \n\<span class="Constant">0</span>\n
</pre></div>
<p>Once you’ve sent the termination sequence you should not attempt to write anything to stdout until getting the next request.</p></div>
    </content>
    <updated>2008-10-19T21:36:22Z</updated>
    <source>
      <id>http://www.davispj.com/</id>
      <author>
        <name>Paul Joseph Davis</name>
        <email>paul.joseph.davis@gmail.com</email>
      </author>
      <link href="http://feeds/couchdb.xml" rel="self" type="application/atom+xml"/>
      <link href="http://www.davispj.com/" rel="alternate" type="text/html"/>
      <subtitle>Semicoherent writings.</subtitle>
      <title>Paul Joseph Davis - CouchDB</title>
      <updated>2008-11-19T05:19:01Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://jchris.mfdz.com/posts/124</id>
    <link href="http://jchris.mfdz.com/posts/124" rel="alternate" type="text/html"/>
    <title>Video: CouchDB Talk at NYC's Arc90</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><br/><a href="http://vimeo.com/1992869?pg=embed&amp;sec=1992869">CouchDB Tech Talk by Chris Anderson</a> from <a href="http://vimeo.com/arc90?pg=embed&amp;sec=1992869">Arc90</a> on <a href="http://vimeo.com?pg=embed&amp;sec=1992869">Vimeo</a>.

	<p>Thanks <a href="http://aviflax.com/">Avi</a> and <a href="http://arc90.com/">Arc90</a> for hosting the event and providing the video.</p>


	<p>The code for <a href="http://github.com/jchris/couchdb-example-blog/tree/master">the example blog is on Github</a></p>


	<p>Also, <a href="http://jchris.mfdz.com/code/2008/10/talk_slides">see this post for slides.</a></p></div>
    </summary>
    <updated>2008-10-19T13:28:04Z</updated>
    <source>
      <id>http://jchris.mfdz.com/posts</id>
      <author>
        <name>Chris Anderson</name>
      </author>
      <link href="http://jchris.mfdz.com/posts" rel="alternate" type="text/html"/>
      <link href="http://jchris.mfdz.com/xml/rss20/feed.xml" rel="self" type="application/rss+xml"/>
      <title>Daytime Running Lights : Coding</title>
      <updated>2008-11-21T16:40:11Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:www.davispj.com,2008-10-19:1224406489</id>
    <link href="http://www.davispj.com/couchdb/views/indexing/idea.html" rel="alternate" type="text/html"/>
    <title>CouchDB View Indexing</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1><a href="http://www.davispj.com/couchdb/views/indexing/idea">CouchDB View Indexing</a></h1>
<h3>See also: <a href="http://www.davispj.com/couchdb/views/indexing/protocol">Line protocol description</a></h3>
<p>This is a fun little patch I wrote today for indexing CouchDB Map/Reduce views. The CouchDB path allows you to setup a process that will listen for Key/Value pairs being added and removed from a view so that you can keep an external index in sync. The patch also exposes a url that you can use to query the view.</p>
<p>A real quick nothing-goes-wrong type of installation would be along the lines of the following:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> $ cd /usr/local/src/temp
<span class="line-numbers">   2 </span> $ git clone git://github.com/davisp/couchdb-lucene.git
<span class="line-numbers">   3 </span> $ cd couchdb-lucene
<span class="line-numbers">   4 </span> $ git checkout -b view_indexer origin/view_indexer
<span class="line-numbers">   5 </span> $ ant
<span class="line-numbers">   6 </span> $ cd ../
<span class="line-numbers">   7 </span> $ git clone git://github.com/davisp/couchdb.git
<span class="line-numbers">   8 </span> $ cd couchdb/trunk
<span class="line-numbers">   9 </span> $ git checkout -b index_server origin/index_server
<span class="line-numbers">  10 </span> $ ./bootstrap <span class="Keyword">&amp;&amp;</span> ./configure <span class="Keyword">&amp;&amp;</span> make
<span class="line-numbers">  11 </span> $ sudo make install
</pre></div>
<p>Assuming that went without any horrific errors, you should edit `/usr/local/etc/couchdb/local.ini`<br/>
to be something like the following.</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Comment"><span class="Comment">;</span> CouchDB Configuration Settings</span>
<span class="line-numbers">   2 </span> 
<span class="line-numbers">   3 </span> <span class="Entity"><span class="Entity">[</span>couchdb<span class="Entity">]</span></span>
<span class="line-numbers">   4 </span> <span class="Comment"><span class="Comment">;</span>max_document_size = 4294967296 ; bytes</span>
<span class="line-numbers">   5 </span> 
<span class="line-numbers">   6 </span> <span class="Entity"><span class="Entity">[</span>httpd<span class="Entity">]</span></span>
<span class="line-numbers">   7 </span> <span class="Comment"><span class="Comment">;</span>port = 5984</span>
<span class="line-numbers">   8 </span> <span class="Comment"><span class="Comment">;</span>bind_address = 127.0.0.1</span>
<span class="line-numbers">   9 </span> 
<span class="line-numbers">  10 </span> <span class="Entity"><span class="Entity">[</span>log<span class="Entity">]</span></span>
<span class="line-numbers">  11 </span> <span class="Keyword">level</span> = debug
<span class="line-numbers">  12 </span> 
<span class="line-numbers">  13 </span> <span class="Entity"><span class="Entity">[</span>daemons<span class="Entity">]</span></span>
<span class="line-numbers">  14 </span> <span class="Keyword">index_servers</span>={couch_index_servers, start_link, []}
<span class="line-numbers">  15 </span> 
<span class="line-numbers">  16 </span> <span class="Entity"><span class="Entity">[</span>index_servers<span class="Entity">]</span></span>
<span class="line-numbers">  17 </span> <span class="Keyword">fti</span>=/usr/local/src/temp/couchdb-lucene/bin/couchdb-lucene-index
<span class="line-numbers">  18 </span> 
<span class="line-numbers">  19 </span> <span class="Entity"><span class="Entity">[</span>httpd_db_handlers<span class="Entity">]</span></span>
<span class="line-numbers">  20 </span> <span class="Keyword">_index</span> = {couch_httpd_view, handle_index_req}
</pre></div>
<p>Pay special attention to line 17 if you changed where you built couchdb-lucene.</p>
<h2>Using the Indexer</h2>
<h4>Example Design Document</h4>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> {
<span class="line-numbers">   2 </span>     <span class="String"><span class="String">"</span>_id<span class="String">"</span></span>: <span class="String"><span class="String">"</span>_design/foo<span class="String">"</span></span>,
<span class="line-numbers">   3 </span>     <span class="String"><span class="String">"</span>_rev<span class="String">"</span></span>: <span class="String"><span class="String">"</span>999203757<span class="String">"</span></span>,
<span class="line-numbers">   4 </span>     <span class="String"><span class="String">"</span>views<span class="String">"</span></span>: {
<span class="line-numbers">   5 </span>         <span class="String"><span class="String">"</span>bar<span class="String">"</span></span>: {
<span class="line-numbers">   6 </span>             <span class="String"><span class="String">"</span>map<span class="String">"</span></span>: <span class="String"><span class="String">"</span>function(doc) {emit(doc.id,doc.value);}<span class="String">"</span></span>,
<span class="line-numbers">   7 </span>             <span class="String"><span class="String">"</span>index<span class="String">"</span></span>: <span class="String"><span class="String">"</span>fti<span class="String">"</span></span>
<span class="line-numbers">   8 </span>         }
<span class="line-numbers">   9 </span>     }
<span class="line-numbers">  10 </span> }
</pre></div>
<h4>Querying the View</h4>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> $ <span class="Comment"><span class="Comment">#</span> Generate some data</span>
<span class="line-numbers">   2 </span> $ curl http://127.0.0.1:5984/dbname/_index/fti/foo/bar?q=<span class="String"><span class="String">"</span>my query<span class="String">"</span></span>
</pre></div>
<h4>Supported Options</h4>
<p>CouchDB-Lucene View-Indexer supports the following <span class="caps">URL</span> parameters:</p>
<ol>
	<li>q → Text query to pass to lucene. Supports the full Lucene syntax (ala org.apache.lucene.queryParser.QueryParser)</li>
	<li>count → Number of documents to return</li>
	<li>skip → Number of documents to skip</li>
</ol></div>
    </content>
    <updated>2008-10-19T08:54:49Z</updated>
    <source>
      <id>http://www.davispj.com/</id>
      <author>
        <name>Paul Joseph Davis</name>
        <email>paul.joseph.davis@gmail.com</email>
      </author>
      <link href="http://feeds/couchdb.xml" rel="self" type="application/atom+xml"/>
      <link href="http://www.davispj.com/" rel="alternate" type="text/html"/>
      <subtitle>Semicoherent writings.</subtitle>
      <title>Paul Joseph Davis - CouchDB</title>
      <updated>2008-11-19T05:19:01Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://jchris.mfdz.com/posts/125</id>
    <link href="http://jchris.mfdz.com/posts/125" rel="alternate" type="text/html"/>
    <title>Talk Slides</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>For those who are interested <a href="http://jchris.googlepages.com/CouchDBtalk.pdf">here is the slide deck (in pdf) corresponding to my talk video</a></p>


	<p>And the slideshare embed:</p>


<div id="__ss_666328" style="width: 425px; text-align: left;"><a href="http://www.slideshare.net/jchrisa/couchdb-talk-jchris-nyc?type=powerpoint" style="font: 14px Helvetica,Arial,Sans-serif; display: block; margin: 12px 0 3px 0; text-decoration: underline;" title="CouchDB Talk JChris NYC">CouchDB Talk JChris <span class="caps">NYC</span></a><div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a href="http://www.slideshare.net/jchrisa/couchdb-talk-jchris-nyc?type=powerpoint" style="text-decoration: underline;" title="View CouchDB Talk JChris NYC on SlideShare">presentation</a> or <a href="http://www.slideshare.net/upload?type=powerpoint" style="text-decoration: underline;">Upload</a> your own.</div></div></div>
    </summary>
    <updated>2008-10-17T22:58:40Z</updated>
    <source>
      <id>http://jchris.mfdz.com/posts</id>
      <author>
        <name>Chris Anderson</name>
      </author>
      <link href="http://jchris.mfdz.com/posts" rel="alternate" type="text/html"/>
      <link href="http://jchris.mfdz.com/xml/rss20/feed.xml" rel="self" type="application/rss+xml"/>
      <title>Daytime Running Lights : Coding</title>
      <updated>2008-11-21T16:40:11Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://bergie.iki.fi/midcom-permalink-d3a5a6fa9ac511ddb9fb4bc603430e8f0e8f</id>
    <link href="http://bergie.iki.fi/blog/free_software_at_work-openpsa2_is_making_a_return/" rel="alternate" type="text/html"/>
    <title>Free software at work: OpenPsa2 is making a return</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>
In the recent <a href="http://www.mindtrek.org/openmind/">OpenMind conference</a> we were discussing how open source projects simply <a href="http://www.linuxforums.org/misc/open_source_will_never_die.html">don't die</a> as long as there is an interested user community: Even if the original company or individual who built the application stops working on it, somebody will always rise and start maintaining it.
</p>

<p>
Last few weeks have been a great example of this. <a href="http://nemein.com/en/">Nemein</a> is the company which originally built the <a href="http://www.openpsa.org/version2">OpenPsa2</a> suite of project management and CRM tools for consulting companies. In last two years there have been some shifts in strategy, and so we ceased working on the product.
</p>

<p>
<a href="http://bergie.iki.fi/midcom-serveattachmentguid-d1ed23569ac511ddb9fb4bc603430e8f0e8f/openpsa2-ragnaroek-20081015.png"><img alt="OpenPsa2 under Midgard Ragnaroek" border="1" height="214" hspace="4" src="http://bergie.iki.fi/midcom-serveattachmentguid-d34177ac9ac511ddb9fb4bc603430e8f0e8f/openpsa2-ragnaroek-20081015-tm.jpg" title="OpenPsa2 under Midgard Ragnaroek" vspace="4" width="400"/></a>
</p>

<p>
Luckily for our users, <a href="http://freshmeat.net/projects/openpsa">OpenPsa has been out</a> under the GNU <a href="http://www.gnu.org/licenses/gpl.html">General Public License</a> <a href="http://bergie.iki.fi/blog/2004-04-29-001/">since 2004</a>. This meant that while commercial development had stopped, they were able to step in and continue where we left off. It took a while, but during this fall <a href="http://www.midgard-project.org/community/whoswho/group/a5767170112c11dca0ce71a6e774ad7bad7b/flack/">Andreas Flack</a> from <a href="http://www.contentcontrol-berlin.de/">Content Control</a> started maintaining the software.
</p>

<p>
Now the effort is starting to bear fruit. <a href="http://www.midgard-project.org/">Midgard</a> world <a href="http://www.midgard-project.org/midgard/8.09/">has recently settled</a> into a new <a href="http://bergie.iki.fi/blog/midgard_and_synchronized_releases/">synchronized release model</a>, and <a href="http://www.midgard-project.org/discussion/developer-forum/openpsa_and_releases/">OpenPsa is swiftly catching up</a> with the rest of the architecture. We expect that it may be released with the <a href="http://trac.midgard-project.org/milestone/8.09.2%20Ragnaroek">Ragnaroek 8.09.2</a> revision.
</p>

<p>
Good work, Andreas!
</p></div>
    </summary>
    <updated>2008-10-15T14:30:34Z</updated>
    <category term="openpsa"/>
    <author>
      <name>Henri Bergius</name>
      <email>henri.bergius@iki.fi</email>
    </author>
    <source>
      <id>http://bergie.iki.fi/blog/</id>
      <author>
        <name/>
        <email>henri.bergius@iki.fi</email>
      </author>
      <link href="http://bergie.iki.fi/blog/" rel="alternate" type="text/html"/>
      <link href="http://bergie.iki.fi/blog/feeds/category/openpsa" rel="self" type="application/rss+xml"/>
      <subtitle>Motorcycle Adventures and Free Software from Henri Bergius</subtitle>
      <title>Henri Bergius: category "openpsa"</title>
      <updated>2008-11-21T16:40:06Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.499</id>
    <link href="http://damienkatz.net/2008/10/washington_washington.html" rel="alternate" type="text/html"/>
    <title>Washington, Washington</title>
    <summary>6 foot 8, weighs a fucking ton. Opponents beware. Opponents beware. He's coming. He's coming. He's coming. Maybe now that I posted it my blog, I can get this song out of head. It's like The Ring. Except infinitely cooler....</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>6 foot 8, weighs a fucking ton.<br/>
Opponents beware.<br/>
Opponents beware.<br/>
He's coming.<br/>
He's coming.<br/>
He's coming.</p>

<p/>

<p>Maybe now that I posted it my blog, I can get this song out of head. It's like The Ring. Except infinitely cooler.</p>

<p>(ps. He's coming. He's coming. He's coming.)</p></div>
    </content>
    <updated>2008-10-10T01:20:44Z</updated>
    <published>2008-10-10T01:07:22Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.498</id>
    <link href="http://damienkatz.net/2008/10/more_couchdb_internals.html" rel="alternate" type="text/html"/>
    <title>More CouchDB internals</title>
    <summary>Peek some more CouchDB internals from Ayende Rahien. Reading Erlang: CouchDB - From REST to Disk in a few function calls Erlang Reading: CouchDB - Digging Down to Disk Reading Eralng: CouchDB Streams Previous CouchDB articles by Ayende....</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>Peek some more CouchDB internals from <a href="http://ayende.com/Blog/">Ayende Rahien</a>.</p>

<p><a href="http://ayende.com/Blog/archive/2008/10/04/reading-erlang-couchdb-from-rest-to-disk-in-a.aspx">Reading Erlang: CouchDB - From REST to Disk in a few function calls</a></p>

<p><a href="http://ayende.com/Blog/archive/2008/10/04/erlang-reading-couchdb-digging-down-to-disk.aspx">Erlang Reading: CouchDB - Digging Down to Disk</a></p>

<p><a href="http://ayende.com/Blog/archive/2008/10/06/reading-eralng-couchdb-streams.aspx">Reading Eralng: CouchDB Streams</a></p>

<p><a href="http://damienkatz.net/2008/09/peek-into-couchdb.html">Previous CouchDB articles by Ayende.</a></p></div>
    </content>
    <updated>2008-10-08T00:11:13Z</updated>
    <published>2008-10-08T00:06:00Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://jchris.mfdz.com/posts/122</id>
    <link href="http://jchris.mfdz.com/posts/122" rel="alternate" type="text/html"/>
    <title>CouchRest::Model - ORM, the CouchDB way</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>There are a few ActiveRecord-style wrappers for <a href="http://couchdb.org">CouchDB</a> out there these days, but many of them have fallen behind as CouchDB’s powers have increased. I’ve taken an interest in writing regular old web apps again – so now is the time when CouchRest grows wings and flies to the vaulted heights of DataMapper and ActiveRecord. (I could have written a DataMapper adapter for CouchDB, but much of DataMapper’s code is based around <span class="caps">SQL</span>-like problems that CouchDB just doesn’t have.) <a href="http://github.com/jchris/couchrest/tree/master/lib/couchrest/core/model.rb">CouchRest::Model provides the ease-of-use Rubyists have come to expect from their ORMs, and it does it in CouchDB style.</a></p>


	<h3>Getting Started</h3>


	<p>Here is an example (taken from the bright shiny new documentation) of what your Models can look like. If you click through to the actual blog post, there is also a longer example <a href="http://gist.github.com/13874">pasted as a gist embed</a> which details the capabilities of the view-generation system even more.</p>


<code>
<pre>class Article &lt;  CouchRest::Model

  use_database CouchRest.database!('http://localhost:5984/couchrest-model-test')
  unique_id :slug

  view_by :date, :descending =&gt; true
  view_by :user_id, :date

  view_by :tags,
    :map =&gt;
      "function(doc) {
        if (doc.type == 'Article' &amp;&amp; doc.tags) {
          doc.tags.forEach(function(tag){
            emit(tag, 1);
          });
        }
      }",
    :reduce =&gt;
      "function(keys, values, rereduce) {
        return sum(values);
      }" 

  key_reader :slug, :created_at, :updated_at
  key_accessor :title, :tags

  # You can make dates work nice without magic or special fields
  key_writer :date 
  def date
    Time.parse(@doc['date'])
  end

  timestamps!

  before(:create, :generate_slug_from_title)
  def generate_slug_from_title
    doc['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'')
  end
end
</pre>
</code>

	<p>You can do the standard <span class="caps">CRUD</span>:</p>


<code><pre>@post = Post.get(params[:id])
@post.title = "New Title" 
@post.save
</pre></code>

	<h3>View Generation</h3>


	<p>The view generation system is what I’m proudest of. It’s designed to be performant, and it strikes a balance between magic and usability. Simple views are as easy to declare as:</p>


<code><pre>  view_by :date, :descending =&gt; true
</pre></code>

	<p>They can be queried easily like this:</p>


<code><pre># get the 10 most recent posts
@posts = Post.by_date :count =&gt; 10

# get the raw view
@view = Post.by_date :count =&gt; 10, :raw =&gt; true
</pre></code>

	<p>Views defined in this way take all the options of a CouchRest::Database#view call, and those options can be provided either as defaults at definition time, or overriden at query time. There is an additional option, :raw, which defaults to false. When :raw is true, you get back just what CouchDB sends. When :raw is false, CouchRest::Model::MagicViews requests the associated document for each view row, and gives you an array of documents. W00t!</p>


	<p>CouchRest::Model views use _design documents, not temp views, so they take advantage of all the performance CouchDB has to offer.</p>


	<p>Views can also be manually composed, if you want to write something that’s more complex than the built-in helpers can provide.</p>


	<p>If you’re at the permalink page for this post, you’ll see <a href="http://gist.github.com/13874">a Gist embed here</a> with an even longer example of CouchRest::Model in action.</p>




	<p>Enjoy!</p></div>
    </summary>
    <updated>2008-10-04T01:13:28Z</updated>
    <source>
      <id>http://jchris.mfdz.com/posts</id>
      <author>
        <name>Chris Anderson</name>
      </author>
      <link href="http://jchris.mfdz.com/posts" rel="alternate" type="text/html"/>
      <link href="http://jchris.mfdz.com/xml/rss20/feed.xml" rel="self" type="application/rss+xml"/>
      <title>Daytime Running Lights : Coding</title>
      <updated>2008-11-21T16:40:11Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:damienkatz.net,2008://1.497</id>
    <link href="http://damienkatz.net/2008/10/in_san_jose_next_week.html" rel="alternate" type="text/html"/>
    <title>In San Jose next week</title>
    <summary>I'll be in San Jose next week, Oct. 8th and 9th. Anyone who wants to meet up, either socially or for business, mail me: damien at damienkatz.net...</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>I'll be in San Jose next week, Oct. 8th and 9th. Anyone who wants to meet up, either socially or for business, mail me: damien at damienkatz.net</p></div>
    </content>
    <updated>2008-10-03T15:48:47Z</updated>
    <published>2008-10-03T15:40:18Z</published>
    <author>
      <name>Damien Katz</name>
    </author>
    <source>
      <id>tag:damienkatz.net,2008-05-05://1</id>
      <link href="http://damienkatz.net/" rel="alternate" type="text/html"/>
      <link href="http://damienkatz.net/atom.xml" rel="self" type="application/atom+xml"/>
      <subtitle>Everybody keeps on talking about it
Nobody's getting it done</subtitle>
      <title>Damien Katz</title>
      <updated>2008-11-21T15:03:41Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:www.davispj.com,2008-10-03:1222992138</id>
    <link href="http://www.davispj.com/couchdb/recipes/joins.html" rel="alternate" type="text/html"/>
    <title>Couchdb Joins</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1><a href="http://www.davispj.com/couchdb/recipes/joins">Couchdb Joins</a></h1>
<p>There has been a fairly active <a href="http://mail-archives.apache.org/mod_mbox/incubator-couchdb-user/200810.mbox/%3C2098F155-ECB7-468E-8CA7-8E54F18EE606@groovie.org%3E">thread</a> on the couchdb-user about how to join couchdb documents. The authoritative documentation on such things so far has been a blog <a href="http://www.cmlenz.net/archives/2007/10/couchdb-joins">post</a> by <a href="http://www.cmlenz.net/">cmlenz</a>. Its a very good introduction into the power of collation. Unfortunately a couple issues keep cropping up on the list generally related to avoiding denormalization in some form or another.</p>
<p>After thinking about the most recent thread I think I’ve managed to sit down and create a couple views that would fulfill the offered requirements. For reference, a short description of the setup:</p>
<h3>The documents</h3>
<ol>
	<li>User documents: A unique non-changing document_id with a cusotmizable username.</li>
	<li>Comment documents: Contain a reference to the user document id.</li>
</ol>
<h3>Goals</h3>
<ol>
	<li>Get a list of users that have comments</li>
	<li>Get a list of users with 5 comments (sorted on some criteria).</li>
</ol>
<h2>General Outline</h2>
<p>All code available <a href="http://www.davispj.com/svn/projects/couchdb-examples/joins/">here</a>.</p>
<p>Briefly, the idea here is to generate a Map/Reduce view that will list the users with comments and the number of comments per user. This is pretty easy but necessary to allow us to get the list of users with their top five comments while ignoring users with no comments.</p>
<p>There are two Map/Reduce views we’ll be using, “with-comments” and “max-comments”. “with-comments” will be responsible for listing the users with the number of their comments. Users with zero comments will not appear in this view. By paging through this view will allow us to walk through the “max-comments” view getting the data we need to display a listing of users with their top N comments. (Sorry, N not configurable at query time.)</p>
<p>I’m using couchview from <a href="http://github.com/jchris/couchrest/tree/master">couchrest</a> to manage my views. Hence the ‘-map’ and ‘-reduce’ suffices on each view name. Both Map/Reduce views are assumed to be placed in a “users” design doc.</p>
<h2>Generating data</h2>
<p>First things first, here’s a script to load some data into a db named “test” on the local host:</p>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Comment"><span class="Comment">#</span>! /usr/bin/env python</span>
<span class="line-numbers">   2 </span> 
<span class="line-numbers">   3 </span> <span class="Keyword">import</span> random
<span class="line-numbers">   4 </span> <span class="Keyword">import</span> uuid
<span class="line-numbers">   5 </span> 
<span class="line-numbers">   6 </span> <span class="Keyword">import</span> couchdb
<span class="line-numbers">   7 </span> 
<span class="line-numbers">   8 </span> server <span class="Keyword">=</span> couchdb.Server(<span class="String"><span class="String">'</span>http://localhost:5984<span class="String">'</span></span>)
<span class="line-numbers">   9 </span> <span class="Keyword">if</span> <span class="String"><span class="String">'</span>test<span class="String">'</span></span> <span class="Keyword">not</span> <span class="Keyword">in</span> server:
<span class="line-numbers">  10 </span>     server.create(<span class="String"><span class="String">'</span>test<span class="String">'</span></span>)
<span class="line-numbers">  11 </span> db <span class="Keyword">=</span> server[<span class="String"><span class="String">'</span>test<span class="String">'</span></span>]
<span class="line-numbers">  12 </span> 
<span class="line-numbers">  13 </span> <span class="Storage">def</span> <span class="Entity">new_uuid</span>():
<span class="line-numbers">  14 </span>     <span class="Keyword">return</span> uuid.uuid4().hex.upper()
<span class="line-numbers">  15 </span> 
<span class="line-numbers">  16 </span> users <span class="Keyword">=</span> <span class="Constant">1000</span>
<span class="line-numbers">  17 </span> docs <span class="Keyword">=</span> []
<span class="line-numbers">  18 </span> <span class="Keyword">for</span> i <span class="Keyword">in</span> <span class="SupportFunction">range</span>(users):
<span class="line-numbers">  19 </span>     uid <span class="Keyword">=</span> new_uuid()
<span class="line-numbers">  20 </span>     docs.append({<span class="String"><span class="String">'</span>_id<span class="String">'</span></span>: uid, <span class="String"><span class="String">'</span>type<span class="String">'</span></span>: <span class="String"><span class="String">'</span>user<span class="String">'</span></span>, <span class="String"><span class="String">'</span>name<span class="String">'</span></span>: <span class="String"><span class="String">'</span>user-<span class="StringConstant">%06d</span><span class="String">'</span></span> <span class="Keyword">%</span> i})
<span class="line-numbers">  21 </span>     <span class="Keyword">for</span> c <span class="Keyword">in</span> <span class="SupportFunction">range</span>(random.randint(<span class="Constant">0</span>,<span class="Constant">25</span>)):
<span class="line-numbers">  22 </span>         cid <span class="Keyword">=</span> new_uuid()
<span class="line-numbers">  23 </span>         docs.append({<span class="String"><span class="String">'</span>_id<span class="String">'</span></span>: cid, <span class="String"><span class="String">'</span>type<span class="String">'</span></span>: <span class="String"><span class="String">'</span>comment<span class="String">'</span></span>, <span class="String"><span class="String">'</span>user_id<span class="String">'</span></span>: uid,
<span class="line-numbers">  24 </span>                     <span class="String"><span class="String">'</span>position<span class="String">'</span></span>: c, <span class="String"><span class="String">'</span>text<span class="String">'</span></span>: <span class="String"><span class="String">"</span>Comment <span class="StringConstant">%d</span> <span class="StringConstant">%d</span><span class="String">"</span></span> <span class="Keyword">%</span> (i, c)})
<span class="line-numbers">  25 </span> 
<span class="line-numbers">  26 </span> db.update(docs)
</pre></div>
<p>So, here we load 1000 users and a random number of comments (0 to 25). Its pretty straight forward. You’ll notice it requires the <a href="http://code.google.com/p/couchdb-python/">couchdb-python</a> module.</p>
<h2>Useres with Number of Comments</h2>
<p>This view is straight forward. Any comments are emitted, and then reduced to a sum. Notice users with zero comments will not show up in the reduce because only rows for each comment are emit()’ed.</p>
<h3>with-comments-map.js</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Storage">function</span>(doc)
<span class="line-numbers">   2 </span> {
<span class="line-numbers">   3 </span>     <span class="Keyword">if</span>(doc.<span class="SupportConstant">type</span> <span class="Keyword">==</span> <span class="String"><span class="String">"</span>comment<span class="String">"</span></span>)
<span class="line-numbers">   4 </span>     {
<span class="line-numbers">   5 </span>         emit([doc.user_id, doc._id], <span class="Constant">1</span>);
<span class="line-numbers">   6 </span>     }
<span class="line-numbers">   7 </span> }
</pre></div>
<h3>with-comments-reduce.js</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Storage">function</span>(keys, values)
<span class="line-numbers">   2 </span> {
<span class="line-numbers">   3 </span>     <span class="Keyword">return</span> sum(values) ;
<span class="line-numbers">   4 </span> }
</pre></div>
<h2>Users with Top N Comments</h2>
<p>This is where things get a bit complicated.</p>
<p>The Map portion is fairly straight forward. For each comment we emit a user id, -1 pair. The -1 is to indicate that this is a user document. Thinking about it now, this is an artifact of an earlier iteration, but any value that is outside the range of comment id’s would be acceptable. (Assuming you change the reduce appropriately)</p>
<p>The reduce function is a bit of wild one. The basic idea is that we’re going to take a set of values and condense them into an object that lists the user_id and top N comments. We have to be careful on re-reduce steps that we can merge these summary objects correctly. A more detailed discussion follows the code.</p>
<h3>max-comments-map.js</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Storage">function</span>(doc)
<span class="line-numbers">   2 </span> {
<span class="line-numbers">   3 </span>     <span class="Keyword">if</span>(doc.<span class="SupportConstant">type</span> <span class="Keyword">==</span> <span class="String"><span class="String">"</span>user<span class="String">"</span></span>)
<span class="line-numbers">   4 </span>     {
<span class="line-numbers">   5 </span>         emit([doc._id, <span class="Keyword">-</span><span class="Constant">1</span>], doc.<span class="SupportConstant">name</span>);
<span class="line-numbers">   6 </span>     }
<span class="line-numbers">   7 </span>     <span class="Keyword">else</span> <span class="Keyword">if</span>(doc.<span class="SupportConstant">type</span> <span class="Keyword">==</span> <span class="String"><span class="String">"</span>comment<span class="String">"</span></span>)
<span class="line-numbers">   8 </span>     {
<span class="line-numbers">   9 </span>         emit([doc.user_id, doc._id], [doc.position, doc.<span class="SupportConstant">text</span>]);
<span class="line-numbers">  10 </span>     }
<span class="line-numbers">  11 </span> }
</pre></div>
<h3>max-comments-reduce.js</h3>

<div class="UltraViolet"><pre class="twilight"><span class="line-numbers">   1 </span> <span class="Storage">function</span>(keys, values, rereduce)
<span class="line-numbers">   2 </span> {
<span class="line-numbers">   3 </span>     <span class="Storage">var</span> MAX <span class="Keyword">=</span> <span class="Constant">5</span> ;
<span class="line-numbers">   4 </span>     <span class="Storage">var</span> obj <span class="Keyword">=</span> <span class="Constant">null</span> ;
<span class="line-numbers">   5 </span> 
<span class="line-numbers">   6 </span>     <span class="Storage">function</span> <span class="Entity">sort_comments</span>(<span class="Variable">a, b</span>)
<span class="line-numbers">   7 </span>     {
<span class="line-numbers">   8 </span>         <span class="Keyword">return</span> a[<span class="Constant">0</span>] <span class="Keyword">-</span> b[<span class="Constant">0</span>] ;
<span class="line-numbers">   9 </span>     }
<span class="line-numbers">  10 </span> 
<span class="line-numbers">  11 </span>     <span class="Storage">function</span> <span class="Entity">add_comment</span>(<span class="Variable">current, to_add</span>)
<span class="line-numbers">  12 </span>     {
<span class="line-numbers">  13 </span>         current[current.<span class="SupportConstant">length</span>] <span class="Keyword">=</span> to_add ;
<span class="line-numbers">  14 </span>         current.<span class="SupportFunction">sort</span>(sort_comments) ;
<span class="line-numbers">  15 </span>         <span class="SupportFunction">log</span>(<span class="String"><span class="String">"</span>Current: <span class="String">"</span></span> <span class="Keyword">+</span> current.<span class="SupportFunction">toSource</span>()) ;
<span class="line-numbers">  16 </span>         <span class="Keyword">return</span> current.<span class="SupportFunction">slice</span>(<span class="Constant">0</span>,MAX) ;
<span class="line-numbers">  17 </span>     }
<span class="line-numbers">  18 </span> 
<span class="line-numbers">  19 </span>     <span class="Keyword">try</span>
<span class="line-numbers">  20 </span>     {
<span class="line-numbers">  21 </span>         <span class="Keyword">if</span>(rereduce)
<span class="line-numbers">  22 </span>         {
<span class="line-numbers">  23 </span>             <span class="Keyword">for</span>(<span class="Storage">var</span> i <span class="Keyword">=</span> <span class="Constant">0</span> ; i <span class="Keyword">&lt;</span> values.<span class="SupportConstant">length</span> ; i<span class="Keyword">++</span>)
<span class="line-numbers">  24 </span>             {
<span class="line-numbers">  25 </span>                 <span class="Keyword">if</span>(<span class="Keyword">typeof</span>(values[i]) <span class="Keyword">==</span> <span class="String"><span class="String">'</span>object<span class="String">'</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> values[i].<span class="SupportConstant">type</span> <span class="Keyword">==</span> <span class="String"><span class="String">'</span>reduction<span class="String">'</span></span>)
<span class="line-numbers">  26 </span>                 {
<span class="line-numbers">  27 </span>                     <span class="Keyword">if</span>(obj <span class="Keyword">==</span> <span class="Constant">null</span>)
<span class="line-numbers">  28 </span>                     {
<span class="line-numbers">  29 </span>                         obj <span class="Keyword">=</span> values[i] ;
<span class="line-numbers">  30 </span>                     }
<span class="line-numbers">  31 </span>                     <span class="Keyword">else</span>
<span class="line-numbers">  32 </span>                     {
<span class="line-numbers">  33 </span>                         <span class="Keyword">if</span>(obj.user_id <span class="Keyword">==</span> <span class="Constant">null</span>)
<span class="line-numbers">  34 </span>                         {
<span class="line-numbers">  35 </span>                             obj.user_id <span class="Keyword">=</span> values[i].user_id ;
<span class="line-numbers">  36 </span>                         }
<span class="line-numbers">  37 </span> 
<span class="line-numbers">  38 </span>                         <span class="Keyword">for</span>(<span class="Storage">var</span> j <span class="Keyword">=</span> <span class="Constant">0</span> ; j <span class="Keyword">&lt;</span> values[i].comments.<span class="SupportConstant">length</span> ; j<span class="Keyword">++</span>)
<span class="line-numbers">  39 </span>                         {
<span class="line-numbers">  40 </span>                             obj.comments <span class="Keyword">=</span> add_comment(obj.comments, values[i].comments[j]) ;
<span class="line-numbers">  41 </span>                         }
<span class="line-numbers">  42 </span>                     }
<span class="line-numbers">  43 </span>                 }
<span class="line-numbers">  44 </span>             }
<span class="line-numbers">  45 </span>         }
<span class="line-numbers">  46 </span> 
<span class="line-numbers">  47 </span>         <span class="Keyword">if</span>(obj <span class="Keyword">==</span> <span class="Constant">null</span>)
<span class="line-numbers">  48 </span>         {
<span class="line-numbers">  49 </span>             obj <span class="Keyword">=</span> {<span class="String"><span class="String">"</span>comments<span class="String">"</span></span>: [], <span class="String"><span class="String">'</span>type<span class="String">'</span></span>: <span class="String"><span class="String">'</span>reduction<span class="String">'</span></span>, <span class="String"><span class="String">'</span>user_id<span class="String">'</span></span>: <span class="Constant">null</span>} ;
<span class="line-numbers">  50 </span>         }
<span class="line-numbers">  51 </span> 
<span class="line-numbers">  52 </span>         <span class="Keyword">if</span>(keys <span class="Keyword">==</span> <span class="Constant">null</span>)
<span class="line-numbers">  53 </span>         {
<span class="line-numbers">  54 </span>             <span class="Keyword">return</span> obj ;
<span class="line-numbers">  55 </span>         }
<span class="line-numbers">  56 </span> 
<span class="line-numbers">  57 </span>         <span class="Keyword">for</span>(<span class="Storage">var</span> i <span class="Keyword">=</span> <span class="Constant">0</span> ; i <span class="Keyword">&lt;</span> keys.<span class="SupportConstant">length</span> ; i<span class="Keyword">++</span>)
<span class="line-numbers">  58 </span>         {
<span class="line-numbers">  59 </span>             <span class="Keyword">if</span>(<span class="Keyword">typeof</span>(values[i]) <span class="Keyword">==</span> <span class="String"><span class="String">'</span>object<span class="String">'</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> values[i].<span class="SupportConstant">type</span> <span class="Keyword">==</span> <span class="String"><span class="String">'</span>reduction<span class="String">'</span></span>)
<span class="line-numbers">  60 </span>             {
<span class="line-numbers">  61 </span>                 <span class="Keyword">continue</span> ;
<span class="line-numbers">  62 </span>             }
<span class="line-numbers">  63 </span> 
<span class="line-numbers">  64 </span>             <span class="Keyword">if</span>(keys[i][<span class="Constant">0</span>][<span class="Constant">1</span>] <span class="Keyword">==</span> <span class="Keyword">-</span><span class="Constant">1</span>)
<span class="line-numbers">  65 </span>             {
<span class="line-numbers">  66 </span>                 obj.user_id <span class="Keyword">=</span> values[i] ;
<span class="line-numbers">  67 </span>             }
<span class="line-numbers">  68 </span>             <span class="Keyword">else</span>
<span class="line-numbers">  69 </span>             {
<span class="line-numbers">  70 </span>                 obj.comments <span class="Keyword">=</span>