<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Mariano Guerra's Log (Posts about couchdb)</title><link>http://marianoguerra.org/</link><description></description><atom:link href="http://marianoguerra.org/categories/couchdb.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Mon, 18 Nov 2024 17:56:42 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>CouchApp V: filtrar documentos por tag ordenados por fecha</title><link>http://marianoguerra.org/posts/201011couchapp-v-filtrar-documentos-por-tag/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;ahora tenemos documentos y para pertenecer a este siglo decidiste agregar tags a algunos elementos para poder filtrarlos y categorizarlos (decí folksonomia y vas a sonar mucho mas hip!)&lt;br&gt;&lt;br&gt;ahora, como filtro documentos por tag?&lt;br&gt;&lt;br&gt;si puedo hacer eso, como filtro por tag y ordeno por fecha?&lt;br&gt;&lt;br&gt;ya que estamos, no seria lindo poder filtrar por tag *y* por fecha?&lt;br&gt;&lt;br&gt;vamos a resolver todos estos requerimientos con una simple vista&lt;br&gt;&lt;br&gt;primero creamos la vista&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;pre&gt;couchapp generate view by-tag&lt;br&gt;&lt;/pre&gt;&lt;br&gt;esto crea una vista en el directorio views llamado by-tag, este es un directorio que contiene dos archivos, map.js y reduce.js&lt;br&gt;&lt;br&gt;en este caso vamos a usar solo map.js asi que borra reduce.js&lt;br&gt;&lt;br&gt;&lt;pre&gt;cd views/by-tag&lt;br&gt;rm reduce.js&lt;br&gt;&lt;/pre&gt;&lt;br&gt;ahora edita map.js para que se vea como esto&lt;br&gt;&lt;br&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;por cada documento en la base de datos, vemos si tiene el atributo tags, si lo tiene, por cada tag en tags emitimos un documento cuya llave es un array con el tag y la fecha y cuyo valor es el documento en si.&lt;br&gt;&lt;br&gt;ahora empujamos los cambios a couchdb&lt;br&gt;&lt;br&gt;&lt;pre&gt;couchapp push&lt;br&gt;&lt;/pre&gt;&lt;br&gt;para probar que funciona, crea algunos documentos con el un campo llamado tags que contenga un array de strings y otro campo llamado created que contenga el timestamp en el que el documento fue creado&lt;br&gt;&lt;br&gt;si pongo esta URL http://localhost:5984/datos/_design/datos/_view/by-tag/ en mi navegador, obtengo algo así:&lt;br&gt;&lt;br&gt;&lt;pre&gt;{"total_rows":8,"offset":0,"rows":[&lt;br&gt;{"id":"d6de7e9a63039dc1af500a40af0014d7","key":["bar",1288644825761],"value":{"_id":"d6de7e9a63039dc1af500a40af0014d7","_rev":"1-eab86fbc2b4c24f31e1d60dfdd762793","author":"wariano", "created":1288644825761, "tags":["test","foo","bar"], ...}},&lt;br&gt;...&lt;br&gt;]}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;esto significa que la vista funciono, ahora para filtrar por tag la URL se va a poner un poco rara&lt;br&gt;&lt;br&gt;vamos a usar filtros en la vista para filtrar solo los documentos con un tag especifico&lt;br&gt;&lt;br&gt;http://localhost:5984/datos/_design/datos/_view/by-tag?descending=false&amp;amp;startkey=["test", 0]&amp;amp;endkey=["test", 9999999999999]&lt;br&gt;&lt;br&gt;con este request decimos que queremos los resultados de la vista llamada by-tag, filtrando los documentos empezando con la llave ["test", 0] y terminando con la llave ["test", 9999999999999]. Esto significa que solo queremos los documentos con la llave "test" y que queremos todos los timestamps (por eso el numero enorme en endkey)&lt;br&gt;&lt;br&gt;si queremos ordenar los tags en orden descendente deberíamos cambiar el orden de starkey y endkey: http://localhost:5984/datos/_design/datos/_view/by-tag?descending=true&amp;amp;startkey=["test", 9999999999999]&amp;amp;endkey=["test", 0]&lt;br&gt;&lt;br&gt;podemos jugar con startkey y endkey para obtener rangos de tags o un tag en un periodo de tiempo especifico, por ejemplo: "cosas taggeadas con fun en los últimos dos días"&lt;br&gt;&lt;br&gt;el código para hacer el request a couchdb desde javascript es el siguiente&lt;br&gt;&lt;br&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nx"&gt;datos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;descending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;okCb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorCb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class="nx"&gt;startStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;endStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;9999999999999&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;descending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;endStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;startStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;couch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;datos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"datos/by-tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"descending"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;descending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"startkey"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;"endkey"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;br&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;okCb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;errorCb&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;con esto tenes una forma de listar documentos por uno o mas campos, podes modificar este ejemplo un poco para listar por usuario o por otras cosas</description><category>couchapp</category><category>couchdb</category><category>javascript</category><category>map</category><category>tags</category><category>views</category><guid>http://marianoguerra.org/posts/201011couchapp-v-filtrar-documentos-por-tag/</guid><pubDate>Tue, 02 Nov 2010 14:34:00 GMT</pubDate></item><item><title>[EN] CouchApp V: filter documents by tag ordered by timestamp</title><link>http://marianoguerra.org/posts/201011en-couchapp-v-filter-documents-by-tag/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;you now have documents and to be in this century you decide to add tags to some elements so you can filter and categorize (say folksonomy and you will sound really hip!)&lt;/p&gt;&lt;br&gt;&lt;p&gt;now, how do I filter the documents by tag?&lt;/p&gt;&lt;br&gt;&lt;p&gt;if I can do that, how do I filter by tag and order by date?&lt;/p&gt;&lt;br&gt;&lt;p&gt;now that we are at it, wouldn't be nice to have a filter by tag *and* date?&lt;/p&gt;&lt;br&gt;&lt;p&gt;we will solve all this requirements with a simple view&lt;/p&gt;&lt;br&gt;&lt;p&gt;first we create the view&lt;/p&gt;&lt;br&gt;&lt;pre&gt;couchapp generate view by-tag&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;this creates a view in the views called by-tags, this is a directory that contains two files, map.js and reduce.js&lt;/p&gt;&lt;br&gt;&lt;p&gt;in this case we will only use the map.js file, so remove the reduce.js file&lt;/p&gt;&lt;br&gt;&lt;pre&gt;cd views/by-tag&lt;br&gt;rm reduce.js&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;now edit the map.js file to look like this&lt;/p&gt;&lt;br&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;p&gt;here for each document in the database we check if the document has the tags attribute and if it has the attribute, for each tag we emit a document that contains as key an array with the tag and timestamp when the document was created and as value the document itself&lt;/p&gt;&lt;br&gt;&lt;p&gt;now we push our changes to couchdb&lt;/p&gt;&lt;br&gt;&lt;pre&gt;couchapp push&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;to test that this works, create some documents with a field called tags that contains a list of strings and a field called created that contain the timestamp when the item was created&lt;/p&gt;&lt;br&gt;&lt;p&gt;if I put this URL http://localhost:5984/datos/_design/datos/_view/by-tag/ in my browser I get something like this&lt;/p&gt;&lt;br&gt;&lt;pre&gt;{"total_rows":8,"offset":0,"rows":[&lt;br&gt;{"id":"d6de7e9a63039dc1af500a40af0014d7","key":["bar",1288644825761],"value":{"_id":"d6de7e9a63039dc1af500a40af0014d7","_rev":"1-eab86fbc2b4c24f31e1d60dfdd762793","author":"wariano", "created":1288644825761, "tags":["test","foo","bar"], ...}},&lt;br&gt;...&lt;br&gt;]}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;this means the view worked, now to filter by tag the URL will get weird&lt;/p&gt;&lt;br&gt;&lt;p&gt;we will use filters in the view to filter only for a specific tag&lt;/p&gt;&lt;br&gt;&lt;p&gt;http://localhost:5984/datos/_design/datos/_view/by-tag?descending=false&amp;amp;startkey=["test", 0]&amp;amp;endkey=["test", 9999999999999]&lt;/p&gt;&lt;br&gt;&lt;p&gt;with this request we say that we want to get the result of the view called by-tag, filtering starting with the key ["test", 0] and ending with the key ["test", 9999999999999]. This means that we only want the documents with the key "test" and we want all the timestamps (that's why the huge number in the endkey&lt;/p&gt;&lt;br&gt;&lt;p&gt;if we want to sort the tags in descending order we should switch the start and endkey like this: http://localhost:5984/datos/_design/datos/_view/by-tag?descending=true&amp;amp;startkey=["test", 9999999999999]&amp;amp;endkey=["test", 0]&lt;/p&gt;&lt;br&gt;&lt;p&gt;we can play with startkey and endkey to get a range of tags or one tag in a specific period, for example, "things tagged fun in the last 2 days"&lt;/p&gt;&lt;br&gt;&lt;p&gt;the code to do the request to couchdb from javascript is the following&lt;/p&gt;&lt;br&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nx"&gt;datos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;descending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;okCb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorCb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class="nx"&gt;startStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;endStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;9999999999999&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;descending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;endStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="nx"&gt;startStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;couch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;datos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"datos/by-tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"descending"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;descending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"startkey"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startStamp&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;"endkey"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endStamp&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;br&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;okCb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;errorCb&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;with this you have a way to list documents by one or more fields, you can modify this a little to list by users, or by some other thing</description><category>couchapp</category><category>couchdb</category><category>javascript</category><category>map</category><category>tags</category><category>views</category><guid>http://marianoguerra.org/posts/201011en-couchapp-v-filter-documents-by-tag/</guid><pubDate>Tue, 02 Nov 2010 14:10:00 GMT</pubDate></item><item><title>CouchApp IV: creando funciones show con templates HTML</title><link>http://marianoguerra.org/posts/201010couchapp-iv-creando-funciones-show-con/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;necesitamos mostrar una entidad en su propia pagina, para eso vamos a necesitar un template html con los valores del documento almacenado en la base de datos, un template es una buena herramienta para eso, veamos como hacerlo en nuestra couchapp&lt;/p&gt;&lt;br&gt;&lt;p&gt;primero creamos la funcion show, esta funcion es llamada para mostrar un documento en algun formato, en nuestro caso html&lt;/p&gt;&lt;br&gt;&lt;pre&gt;# generamos la funcion show&lt;br&gt;couchapp generate show dato&lt;br&gt;# la editamos con un editor de texto&lt;br&gt;vim shows/dato.js&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;en un principio vamos a ver este contenido&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;pre&gt;function(doc, req) {  &lt;br&gt;&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;reemplazamos por algo parecido a esto&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;pre&gt;function(doc, req) {&lt;br&gt;    if (doc !== null &amp;amp;&amp;amp; doc.name) {&lt;br&gt;        var ddoc = this,&lt;br&gt;            Mustache = require("vendor/couchapp/lib/mustache"),&lt;br&gt;            path = require("vendor/couchapp/lib/path").init(req),&lt;br&gt;            assetPath = path.asset();&lt;br&gt;&lt;br&gt;        provides("html", function() {&lt;br&gt;            return Mustache.to_html(ddoc.templates.dato, {&lt;br&gt;                assetPath: assetPath,&lt;br&gt;                doc: doc&lt;br&gt;            });&lt;br&gt;        });&lt;br&gt;    }&lt;br&gt;    else {&lt;br&gt;        return "not found";&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;en el codigo controlamos que tenemos un documento, sino mostramos "not found", &lt;br&gt;tambien creamos algunos objetos que nos ayudan y finalmente renderizamos el template pasandole algunos valores que seran usados dentro del template.&lt;/p&gt;&lt;br&gt;&lt;p&gt;mi template esta en templates/dato.html (por eso ddoc.templates.dato) y contiene un template mustache, mira &lt;a href="http://mustache.github.com/"&gt;la documentacion de mustache&lt;/a&gt; para mas informacion sobre el formato&lt;/p&gt;&lt;br&gt;&lt;p&gt;la url par acceder a esta funcion es [database]/_design/[app]/_show/[showname]/[docid] un ejemplo podria ser http://localhost:5984/datos/_design/datos/_show/dato/6bd97648d74961996c8f0d42b2005761&lt;/p&gt;</description><category>couchapp</category><category>couchdb</category><category>mustache</category><category>templates</category><guid>http://marianoguerra.org/posts/201010couchapp-iv-creando-funciones-show-con/</guid><pubDate>Fri, 22 Oct 2010 21:20:00 GMT</pubDate></item><item><title>[EN] CouchApp IV: creating show functions with html templates</title><link>http://marianoguerra.org/posts/201010en-couchapp-iv-creating-show-functions/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;we need to display some entity in its own web page, for that we need to fill an html template with the values of the document stores in the database, a template is a nice fit for this, let's see how we do this in our couchapp&lt;/p&gt;&lt;br&gt;&lt;p&gt;first, create the show function, this is a function that when called displays a document in some format, in our case in HTML&lt;/p&gt;&lt;br&gt;&lt;pre&gt;# generate the show function&lt;br&gt;couchapp generate show dato&lt;br&gt;# open it with a text editor&lt;br&gt;vim shows/dato.js&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;we will see this content&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;pre&gt;function(doc, req) {  &lt;br&gt;&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;we replace the content with something like this&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;pre&gt;function(doc, req) {&lt;br&gt;    if (doc !== null &amp;amp;&amp;amp; doc.name) {&lt;br&gt;        var ddoc = this,&lt;br&gt;            Mustache = require("vendor/couchapp/lib/mustache"),&lt;br&gt;            path = require("vendor/couchapp/lib/path").init(req),&lt;br&gt;            assetPath = path.asset();&lt;br&gt;&lt;br&gt;        provides("html", function() {&lt;br&gt;            return Mustache.to_html(ddoc.templates.dato, {&lt;br&gt;                assetPath: assetPath,&lt;br&gt;                doc: doc&lt;br&gt;            });&lt;br&gt;        });&lt;br&gt;    }&lt;br&gt;    else {&lt;br&gt;        return "not found";&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;here we check that we have a document, if not return "not found", also we create some objects that will help us and finally we render the template passing some values that will be used in the template.&lt;/p&gt;&lt;br&gt;&lt;p&gt;my template is located at templates/dato.html (that's why ddoc.templates.dato) and contains a mustache template, see &lt;a href="http://marianoguerra.org/posts/201010en-couchapp-iv-creating-show-functions/%22http:/mustache.github.com/%22"&gt;mustache documentation for information about the format&lt;/a&gt;&lt;/p&gt;&lt;br&gt;&lt;p&gt;the url to access this function is [database]/_design/[app]/_show/[showname]/[docid] an example could be http://localhost:5984/datos/_design/datos/_show/dato/6bd97648d74961996c8f0d42b2005761&lt;/p&gt;</description><category>couchapp</category><category>couchdb</category><category>mustache</category><category>templates</category><guid>http://marianoguerra.org/posts/201010en-couchapp-iv-creating-show-functions/</guid><pubDate>Fri, 22 Oct 2010 21:15:00 GMT</pubDate></item><item><title>CouchApp III: subiendo los cambios automaticamente</title><link>http://marianoguerra.org/posts/201010couchapp-iii-subiendo-los-cambios/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;ahora que tenemos todo lo que necesitamos para crear nuestra couchapp, podemos ir al directorio _attachments y empezar a modificar el código para que haga lo que queramos&lt;/p&gt;&lt;br&gt;&lt;p&gt;después de un rato vas a notar que necesitas hacer push de los cambios a couchdb cada vez que queres probarlos, si sos como yo esto se va a poner molesto bastante rápido, hagamos que las herramientas nos ayuden&lt;/p&gt;&lt;br&gt;&lt;pre&gt;#install inotify-tools&lt;br&gt;sudo apt-get install inotify-tools&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;con inotify tools vamos a correr un script que va a monitorear cualquier cambio de archivos y va a hacer un push cuando eso suceda, voy a excluir los cambios en *.swp ya que vim crea esos archivos y cambian bastante seguido&lt;/p&gt;&lt;br&gt;&lt;p&gt;corre este comando en algún shell y dejalo corriendo&lt;/p&gt;&lt;br&gt;&lt;pre&gt;inotifywait -q -e modify -m -r . | while read line; do if echo $line | grep -v .*.swp; then couchapp push; fi; done&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;ahora edita algún archivo y guardalo, anda al shell donde tenes el script corriendo, vas a ver algo como esto:&lt;/p&gt;&lt;br&gt;&lt;pre&gt;./_attachments/ MODIFY index.html&lt;br&gt;2010-10-22 11:00:48 [INFO] Visit your CouchApp here:&lt;br&gt;http://wariano:secret@localhost:5984/datos/_design/datos/index.html&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;ahora podes editar tus archivos y los cambios van a ser automáticamente subidos a couchdb&lt;/p&gt;</description><category>couchapp</category><category>couchdb</category><category>fiaca</category><guid>http://marianoguerra.org/posts/201010couchapp-iii-subiendo-los-cambios/</guid><pubDate>Fri, 22 Oct 2010 15:12:00 GMT</pubDate></item><item><title>[EN] CouchApp III: pushing the changes automatically</title><link>http://marianoguerra.org/posts/201010en-couchapp-iii-pushing-changes/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;now we have all we need to start creating our couchapp, go to the _attachments directory and start modifying the code to do what you want&lt;/p&gt;&lt;br&gt;&lt;p&gt;after a moment you will notice that you need to push the changes to couchdb each time you want to test it, if you are like me this will get annoying pretty fast, let's make the tools help us&lt;/p&gt;&lt;br&gt;&lt;pre&gt;#install inotify-tools&lt;br&gt;sudo apt-get install inotify-tools&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;with inotify tools we will run a script that will monitor any file change and make a couchapp push when that happens, I will exclude the changes in *.swp files since vim create those and they change pretty often&lt;/p&gt;&lt;br&gt;&lt;p&gt;in some shell run this and leave it running&lt;/p&gt;&lt;br&gt;&lt;pre&gt;inotifywait -q -e modify -m -r . | while read line; do if echo $line | grep -v .*.swp; then couchapp push; fi; done&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;now edit some file and save it, go back to the shell where the script is running, you should see something like:&lt;/p&gt;&lt;br&gt;&lt;pre&gt;./_attachments/ MODIFY index.html&lt;br&gt;2010-10-22 11:00:48 [INFO] Visit your CouchApp here:&lt;br&gt;http://wariano:secret@localhost:5984/datos/_design/datos/index.html&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;now you can edit your files and the changes will be pushed automatically to couchdb&lt;/p&gt;</description><category>couchapp</category><category>couchdb</category><category>fiaca</category><guid>http://marianoguerra.org/posts/201010en-couchapp-iii-pushing-changes/</guid><pubDate>Fri, 22 Oct 2010 15:07:00 GMT</pubDate></item><item><title>CouchApp II: arreglando la fiesta de admins</title><link>http://marianoguerra.org/posts/201010couchapp-ii-arreglando-la-fiesta-de/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;ahora que tenemos nuestra aplicacion corriendo podemos ver que hay un problema con la demo, no tenemos autenticacion, por default couchdb esta en modo "fiesta de admins", para leer mas sobre la fiesta de admins en couchdb podes leer &lt;a href="http://guide.couchdb.org/draft/security.html#party"&gt;Couchdb the definitive guide&lt;/a&gt;&lt;/p&gt; &lt;br&gt;&lt;p&gt;para arreglarlo necesitamos usar futon (el panel administrativo de couchdb) y crear el primer admin&lt;/p&gt;&lt;br&gt;&lt;p&gt;anda a futon con tu browser a http://localhost:5984/_utils/index.html&lt;/p&gt;&lt;br&gt;&lt;p&gt;abajo a la derecha de la pagina deberias leer algo como "Welcome to Admin Party! Everyone is admin. Fix this", hace click en el link y crea el primer admin&lt;/p&gt;&lt;br&gt;&lt;p&gt;voy a crear el admin como "wariano" y como password "secret", cuando veas esto deberías cambiarlo por tu usuario y password&lt;/p&gt;&lt;br&gt;&lt;p&gt;si intentamos hacer push de nuestra couchapp de nuevo vamos a obtener un error que nos dice que no estamos autorizados, esto es porque necesitamos proveer usuario y contraseña para modificar la base de datos ahora, para hacer esto vamos a editar el archivo .couchapprc de nuevo para agregar el usuario y contraseña&lt;/p&gt;&lt;br&gt;&lt;p&gt;edita la url de&lt;/p&gt;&lt;br&gt;&lt;pre&gt;http://localhost:5984/datos&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;a&lt;/p&gt;&lt;br&gt;&lt;pre&gt;http://wariano:secret@localhost:5984/datos&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;intenta hacer push de nuevo, debería funcionar. Intenta usar la demo de nuevo usando tu usuario y contraseña&lt;/p&gt;</description><category>couchapp</category><category>couchdb</category><category>seguridad</category><guid>http://marianoguerra.org/posts/201010couchapp-ii-arreglando-la-fiesta-de/</guid><pubDate>Fri, 22 Oct 2010 14:55:00 GMT</pubDate></item><item><title>[EN] CouchApp II: fixing the admin party</title><link>http://marianoguerra.org/posts/201010couchapp-ii-fixing-admin-party/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;now that we have our app running we can see a problem in the demo, we don't have authentication, and by default couchdb is in "admin party" mode, read more about the admin party in &lt;a href="http://guide.couchdb.org/draft/security.html#party"&gt;Couchdb the definitive guide&lt;/a&gt;&lt;/p&gt;&lt;br&gt;&lt;p&gt;to fix  this we need to go to futon (the admin panel of couchdb) and set up the first admin&lt;/p&gt;&lt;br&gt;&lt;p&gt;go to futon pointing your browser to http://localhost:5984/_utils/index.html&lt;/p&gt;&lt;br&gt;&lt;p&gt;at the bottom right corner of the page you should read something like "Welcome to Admin Party! Everyone is admin. Fix this", click on the link and set the first admin&lt;/p&gt;&lt;br&gt;&lt;p&gt;I will create the admin as "wariano" and password "secret", whenever you see that change for your user and password&lt;/p&gt;&lt;br&gt;&lt;p&gt;if we try to push our couchapp again we will get an unauthorized error, that's because we need to provide credentials to modify the database now, to do this we will edit the .couchapprc again to add the user and password&lt;/p&gt;&lt;br&gt;&lt;p&gt;edit the url from&lt;/p&gt;&lt;br&gt;&lt;pre&gt;http://localhost:5984/datos&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;to&lt;/p&gt;&lt;br&gt;&lt;pre&gt;http://wariano:secret@localhost:5984/datos&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;and try pushing again it should work now, try the demo again using your user and password&lt;/p&gt;</description><category>admin party</category><category>couchapp</category><category>couchdb</category><category>security</category><guid>http://marianoguerra.org/posts/201010couchapp-ii-fixing-admin-party/</guid><pubDate>Fri, 22 Oct 2010 14:45:00 GMT</pubDate></item><item><title>CouchApp I: instalando el entorno</title><link>http://marianoguerra.org/posts/201010couchapp-i-instalando-el-entorno/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;vamos a empezar nuestra couchapp instalando el entorno, para eso necesitamos instalar couchapp y couchdb&lt;/p&gt;&lt;br&gt;&lt;pre&gt;# instalar couchdb y los modulos de python para poder instalar otros modulos&lt;br&gt;sudo apt-get install python-setuptools couchdb&lt;br&gt;# descargar pip&lt;br&gt;curl -O http://python-distribute.org/distribute_setup.py&lt;br&gt;sudo python distribute_setup.py&lt;br&gt;sudo easy_install pip&lt;br&gt;# instalar couchapp&lt;br&gt;sudo pip install couchapp&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;ahora que tenemos couchapp vamos a generar nuestro proyecto, vamos a llamarlo "datos"&lt;/p&gt;&lt;br&gt;&lt;pre&gt;couchapp generate datos&lt;br&gt;cd datos&lt;br&gt;# editamos el archivo couchapprc&lt;br&gt;vim .couchapprc&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;el archivo .couchapprc contiene los destinos donde vamos a instalar nuestra aplicación, definamos el target por defecto&lt;/p&gt;&lt;br&gt;&lt;pre&gt;{"env": {&lt;br&gt;  "default": {&lt;br&gt;   "db": "http://localhost:5984/datos"&lt;br&gt;  }&lt;br&gt; }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;guardar el contenido y correr&lt;/p&gt;&lt;br&gt;&lt;pre&gt;couchapp push&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;deberia mostrar algo como lo siguiente:&lt;/p&gt;&lt;br&gt;&lt;pre&gt;2010-10-22 10:21:10 [INFO] Visit your CouchApp here:&lt;br&gt;http://localhost:5984/datos/_design/datos/index.html&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;ahora anda a esa URL con tu browser, deberías ver la pagina de demostración.&lt;/p&gt;</description><category>couchapp</category><category>couchdb</category><category>javascript</category><guid>http://marianoguerra.org/posts/201010couchapp-i-instalando-el-entorno/</guid><pubDate>Fri, 22 Oct 2010 14:29:00 GMT</pubDate></item><item><title>[EN] CouchApp I: setting up the environment</title><link>http://marianoguerra.org/posts/201010en-couchapp-i-setting-up-environment/</link><dc:creator>Mariano Guerra</dc:creator><description>&lt;p&gt;we will start our couchapp setting up the environment, for that we will install couchdb and couchapp&lt;/p&gt;&lt;br&gt;&lt;pre&gt;# install couchdb and python modules to install other modules&lt;br&gt;sudo apt-get install python-setuptools couchdb&lt;br&gt;# download pip&lt;br&gt;curl -O http://python-distribute.org/distribute_setup.py&lt;br&gt;sudo python distribute_setup.py&lt;br&gt;sudo easy_install pip&lt;br&gt;# install couchapp&lt;br&gt;sudo pip install couchapp&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;now that we have couchapp we will generate our project, we will call it "datos"&lt;/p&gt;&lt;br&gt;&lt;pre&gt;couchapp generate datos&lt;br&gt;cd datos&lt;br&gt;# edit the couchapprc file&lt;br&gt;vim .couchapprc&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;the .couchapprc file contains the targets where we can deploy our application, let's define the default target&lt;/p&gt;&lt;br&gt;&lt;pre&gt;{"env": {&lt;br&gt;  "default": {&lt;br&gt;   "db": "http://localhost:5984/datos"&lt;br&gt;  }&lt;br&gt; }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;save the content and run&lt;/p&gt;&lt;br&gt;&lt;pre&gt;couchapp push&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;it should display something like the following:&lt;/p&gt;&lt;br&gt;&lt;pre&gt;2010-10-22 10:21:10 [INFO] Visit your CouchApp here:&lt;br&gt;http://localhost:5984/datos/_design/datos/index.html&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;p&gt;now go to that site with your browser, you should see a demo page.&lt;/p&gt;</description><category>couchapp</category><category>couchdb</category><category>javascript</category><category>json</category><guid>http://marianoguerra.org/posts/201010en-couchapp-i-setting-up-environment/</guid><pubDate>Fri, 22 Oct 2010 14:26:00 GMT</pubDate></item></channel></rss>