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

<channel>
	<title>P3M &#187; CouchDB</title>
	<atom:link href="http://www.p3m.com.br/blog/category/couchdb/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.p3m.com.br/blog</link>
	<description>Ruby on Rails, PHP, MySQL</description>
	<lastBuildDate>Mon, 30 Aug 2010 14:41:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>CouchDB Lucene &#8211; Buscas Full-text no CouchDB</title>
		<link>http://www.p3m.com.br/blog/couchdb-lucene-buscas-full-text-no-couchdb/</link>
		<comments>http://www.p3m.com.br/blog/couchdb-lucene-buscas-full-text-no-couchdb/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 14:07:20 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[couchdb lucene]]></category>
		<category><![CDATA[full text]]></category>
		<category><![CDATA[full text couchdb]]></category>
		<category><![CDATA[lucene]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=185</guid>
		<description><![CDATA[O CouchDB Lucene provê a funcionalidade de realizar buscas full-text no CouchDB utilizando Lucene. Antes de começar precisamos instalar as dependências, só lembrando que esse tutorial foi testado nas versões 10.04 e 9.10 do Ubuntu Linux, mas a princípio o procedimento de instalação para Mac deve ser parecido. No Ubuntu 10.04 os pacotes sun-java6 foram [...]]]></description>
			<content:encoded><![CDATA[<p>O <a rel="nofollow" href="http://github.com/rnewson/couchdb-lucene" target="_blank">CouchDB Lucene</a> provê a funcionalidade de realizar buscas full-text no <a href="http://www.p3m.com.br/blog/couchdb/">CouchDB</a> utilizando <a rel="nofollow" href="http://lucene.apache.org/" target="_blank">Lucene</a>.</p>
<p>Antes de começar precisamos instalar as dependências, só lembrando que esse tutorial foi testado nas versões 10.04 e 9.10 do Ubuntu Linux, mas a princípio o procedimento de instalação para Mac deve ser parecido.<br />
No Ubuntu 10.04 os pacotes <a rel="nofollow" href="http://andrenoel.com.br/2010/04/26/cade-o-meu-plugin-do-java/" target="_blank">sun-java6 foram removidos da seção Multiverse do Ubuntu archive</a>, então você precisa adicionar o repositório Partner da Canonical.</p>
<pre class="brush: bash;">
sudo add-apt-repository &quot;deb http://archive.canonical.com/ lucid partner&quot;
</pre>
<p>Então você pode <a rel="nofollow" href="http://www.cyberciti.biz/faq/howto-ubuntu-linux-install-configure-jdk-jre/" target="_blank">instalar o JDK e o JRE</a>:</p>
<pre class="brush: bash;">
sudo apt-get install sun-java6-bin sun-java6-jre sun-java6-jdk
</pre>
<p>Para instalar o CouchDB Lucene é preciso que você tenha o <a rel="nofollow" href="http://git-scm.com/" target="_blank">Git</a> e o <a rel="nofollow" href="http://maven.apache.org/" target="_blank">Maven</a> instalados:</p>
<pre class="brush: bash;">
sudo apt-get install git-core maven2
</pre>
<p>Finalmente para instalar o CouchDB Lucene é necessário clonar o repositório:</p>
<pre class="brush: bash;">
git clone git://github.com/rnewson/couchdb-lucene.git
</pre>
<p>No caso, hoje a versão estável é a 0.5.3, então vamos dar o build:</p>
<pre class="brush: bash;">
cd couchdb-lucene
git checkout v0.5.3
mvn
</pre>
<p><strong>Configurando o CouchDB</strong><br />
Agora vamos configurar o CouchDB editando o arquivo de configuração que geralmente está localizado em <em>/usr/local/etc/couchdb/local.ini</em></p>
<pre class="brush: plain;">
[couchdb]
os_process_timeout=60000 ; aumenta o timeout para 5 segundos

[external]
fti=/path/do/python /path/para/couchdb-lucene/tools/couchdb-external-hook.py ; geralmente /usr/bin/python

[httpd_db_handlers]
_fti = {couch_httpd_external, handle_external_req, &lt;&lt;&quot;fti&quot;&gt;&gt;}
</pre>
<p>Agora vamos criar uma view de exemplo, supondo que temos um <strong>design document</strong> de Posts</p>
<pre class="brush: jscript;">
{
    &quot;_id&quot;: &quot;_design/Post&quot;,
    &quot;fulltext&quot;: {
        &quot;by_title&quot;: {
            &quot;index&quot;: &quot;
            function(doc) {
                if(doc['couchrest-type'] == 'Post') {
                    var ret=new Document();
                    ret.add(doc.title);
                    return ret;
                }
            }&quot;
        }
    }
}
</pre>
<p>Pronto, você pode realizar buscas full-text no CouchDB utilizando Lucene:</p>
<pre class="brush: bash;">
curl http://localhost:5984/nome_banco/_fti/_design/Post/by_title?q=titulo_do_post
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/couchdb-lucene-buscas-full-text-no-couchdb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Group by no Couchdb</title>
		<link>http://www.p3m.com.br/blog/group-by-no-couchdb/</link>
		<comments>http://www.p3m.com.br/blog/group-by-no-couchdb/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 21:32:06 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[group by couchdb]]></category>
		<category><![CDATA[group level]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[views couchdb]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=170</guid>
		<description><![CDATA[No post anterior sobre Order by no CouchDB eu mencionei que o próximo post seria sobre Group by, como prometido vou tentar abordar essa questão apresentando um exemplo simples de como agrupar resultados de views. Para facilitar (como sempre) estou utilizando Ruby on Rails + CouchRest, porém vou postar aqui só a parte relevante do [...]]]></description>
			<content:encoded><![CDATA[<p>No post anterior sobre <a href="http://www.p3m.com.br/blog/order-by-no-couchdb/" target="_blank">Order by no CouchDB</a> eu mencionei que o próximo post seria sobre Group by, como prometido vou tentar abordar essa questão apresentando um exemplo simples de como agrupar resultados de views.</p>
<p>Para facilitar (como sempre) estou utilizando <strong>Ruby on Rails + CouchRest</strong>, porém vou postar aqui só a parte relevante do código para entendermos o exemplo. Então vamos considerar nosso model Post:</p>
<pre class="brush: ruby;">
class Post &lt; CouchRest::ExtendedDocument
  use_database CouchRest.database(&quot;http://127.0.0.1:5984/group_couchdb&quot;)

  property :titulo
  property :conteudo
  property :autor_id

  timestamps!

  view_by :data,
  :map =&gt; &quot;
    function(doc) {
      if ((doc['couchrest-type'] == 'Post')) {
        data = doc.created_at;
        ano = parseInt(data.substr(0, 4));
        mes = parseInt(data.substr(5, 2), 10);
        dia = parseInt(data.substr(8, 2), 10);

        emit([ano, mes, dia], 1);
      }
    }&quot;,
  :reduce =&gt; &quot;_count&quot;

end
</pre>
<p>Detalhe para a view <em>data</em> que emite como chave um array contendo o ano, mes e dia do post e para cada valor (dependendo do agrupamento) emite o valor 1 para a <strong>função reduce</strong> (que conta quantos valores foram emitidos para cada chave em questão).</p>
<p>Não vou postar o código de inserção dos posts, você pode inserir alguns posts na sua base para realizar os testes.<br />
Primeiro quero contar o número de posts realizados por dia (isso é possível pois a função map gera o array com dia, mês e ano, assim a função reduce soma os valores para as chaves).</p>
<pre class="brush: bash;">
curl http://127.0.0.1:5984/group_couchdb/_design/Post/_view/by_data?group=true
</pre>
<p>Acessando a url acima você vai ver um resultado parecido com esse:</p>
<pre class="brush: jscript;">
{&quot;rows&quot;:[
  {&quot;key&quot;:[2010,6,10],&quot;value&quot;:1},
  {&quot;key&quot;:[2010,7,17],&quot;value&quot;:1},
  {&quot;key&quot;:[2010,7,18],&quot;value&quot;:2}
]}
</pre>
<p>Ou seja, no dia 10/06/2010 foi cadastrado um post, assim como no dia 17/07/2010, já no dia 18/07/2010 foram cadastrados dois posts (esses são os posts que eu tenho cadastrado na minha base).</p>
<p>Agora vamos supor que queremos contar quantos posts foram cadastrados por ano. Isso é muito simples utilizando a view que já temos, o CouchDB aceita um parâmetro chamado <strong>group_level</strong>. Cada posição do array que foi emitida é um &#8220;level&#8221;, então podemos agrupar os valores por cada posição do array. Se passarmos group_level=2 serão emitidos como chave o ano e o mês, group_level=1 apenas o mês, etc.</p>
<pre class="brush: ruby;">
Post.by_data(:reduce =&gt; true, :group_level=&gt;1)
</pre>
<p>A url seria parecida com essa:</p>
<pre class="brush: bash;">

http://127.0.0.1:5984/group_couchdb/_design/Post/_view/by_data?group=true&amp;group_level=1
</pre>
<p>E o resultado seria quatro posts para o ano de 2010</p>
<pre class="brush: jscript;">
{&quot;rows&quot;:[
  {&quot;key&quot;:[2010],&quot;value&quot;:4}
]}
</pre>
<p>Podemos concluir que agrupar valores no CouchDB não é tão difícil quanto parece, acredito que é uma questão da modelagem dos dados e da forma como utilizamos as views.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/group-by-no-couchdb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Order by no CouchDB</title>
		<link>http://www.p3m.com.br/blog/order-by-no-couchdb/</link>
		<comments>http://www.p3m.com.br/blog/order-by-no-couchdb/#comments</comments>
		<pubDate>Tue, 25 May 2010 02:23:00 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[order by]]></category>
		<category><![CDATA[order by couchdb]]></category>
		<category><![CDATA[view indexes]]></category>
		<category><![CDATA[views couchdb]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=172</guid>
		<description><![CDATA[Uma das cláusulas mais utilizadas em SQL nos bancos relacionais é a ORDER BY. Sempre que queremos ordenar o resultado de uma query por determinada coluna de uma tabela, utilizamos ORDER BY nome_da_coluna e recomenda-se que seja criado um índice para essa coluna, afim de otimizar a ordenação dos dados. O problema começa quando precisamos [...]]]></description>
			<content:encoded><![CDATA[<p>Uma das cláusulas mais utilizadas em SQL nos bancos relacionais é a <strong>ORDER BY</strong>. Sempre que queremos ordenar o resultado de uma query por determinada coluna de uma tabela, utilizamos <strong>ORDER BY nome_da_coluna</strong> e recomenda-se que seja criado um índice para essa coluna, afim de otimizar a ordenação dos dados. O problema começa quando precisamos ordernar os resultados por vários campos da tabela, sendo que pode ficar inviável criar uma série de índices, já que essa tabela pode também sofrer um grande número de atualizações.</p>
<p>Uma das grandes vantagens do <a href="http://www.p3m.com.br/blog/couchdb/">CouchDB</a> (noSQL) é o poder das <a href="http://books.couchdb.org/relax/design-documents/views#What%20is%20a%20View?" rel="nofollow" target="_blank">views</a> (eu sempre gosto de reforçar isso). Você pode criar várias views (que resultem em várias formas) para os seus dados, sem comprometer a inserção para aquele tipo de dado (documento). Ou seja, supondo que você precise ordenar alguns documentos por 3 &#8220;campos&#8221; diferentes, basta que você crie 3 views, sendo que cada uma emita como chave o determinado &#8220;campo&#8221; em questão. Podemos exemplificar em Ruby utilizando a gem <a href="http://github.com/couchrest/couchrest" rel="nofollow" target="_blank">CouchRest</a>, vamos supor um modelo de cidades:</p>
<pre class="brush: ruby;">
class City &lt; CouchRest::ExtendedDocument
  use_database CouchRest.database(&quot;http://127.0.0.1:5984/order_by_couchdb&quot;)
  unique_id :slug

  property :slug, :read_only =&gt; true
  property :name
  property :state
  property :population
  timestamps!

  #o couchrest criara as views no banco
  view_by :name
  view_by :state
  view_by :population

  #antes de salvar cria o slug que sera o id do documento
  set_callback :save, :before, :generate_slug_from_name

  def generate_slug_from_name
    self['slug'] = name.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'') if new?
  end
end
</pre>
<p>Vamos inserir algumas cidades para exemplificar (eu estou utilizando Rails também)</p>
<pre class="brush: ruby;">
c = City.new(:name =&gt; &quot;Sorocaba&quot;, :state =&gt; &quot;SP&quot;, :population =&gt; 700000)
c.save

c2 = City.new(:name =&gt; &quot;Sao Paulo&quot;, :state =&gt; &quot;SP&quot;, :population =&gt; 11000000)
c2.save

c3 = City.new(:name =&gt; &quot;Rio de Janeiro&quot;, :state =&gt; &quot;RJ&quot;, :population =&gt; 6000000)
c3.save
</pre>
<p>O CouchRest vai criar 3 views (by_name, by_state, by_population). Ordenando as cidades pelo nome</p>
<pre class="brush: ruby;">
City.by_name
</pre>
<p>Repare que no banco será criada a view (função map)</p>
<pre class="brush: jscript;">
function(doc) {
  if ((doc['couchrest-type'] == 'City') &amp;&amp; doc['name']) {
    emit(doc['name'], null);
  }
}
</pre>
<p>E o resultado será (ordenado alfabeticamente)</p>
<pre class="brush: jscript;">
{&quot;total_rows&quot;:3,&quot;offset&quot;:0,&quot;rows&quot;:[
  {&quot;id&quot;:&quot;rio-de-janeiro&quot;,&quot;key&quot;:&quot;Rio de Janeiro&quot;,&quot;value&quot;:null},
  {&quot;id&quot;:&quot;sao-paulo&quot;,&quot;key&quot;:&quot;Sao Paulo&quot;,&quot;value&quot;:null},
  {&quot;id&quot;:&quot;sorocaba&quot;,&quot;key&quot;:&quot;Sorocaba&quot;,&quot;value&quot;:null}
]}
</pre>
<p>Ordenando as cidades pelo número da população, da maior para a menor</p>
<pre class="brush: ruby;">
City.by_population(:descending =&gt; true)
</pre>
<pre class="brush: jscript;">
{&quot;total_rows&quot;:3,&quot;offset&quot;:0,&quot;rows&quot;:[
  {&quot;id&quot;:&quot;sao-paulo&quot;,&quot;key&quot;:11000000,&quot;value&quot;:null},
  {&quot;id&quot;:&quot;rio-de-janeiro&quot;,&quot;key&quot;:6000000,&quot;value&quot;:null},
  {&quot;id&quot;:&quot;sorocaba&quot;,&quot;key&quot;:600000,&quot;value&quot;:null}
]}
</pre>
<p>Até aí tudo muito simples e fácil, podemos ordenar nossos dados de forma bem <strong>flexível</strong>. Então, vamos complicar um pouco. Vamos supor que queremos filtrar os resultados passando como parâmetro o estado, porém que as cidades sejam ordenadas pela data de criação, de forma que as mais velhas sejam mostradas primeiro. A princípio isso parece estranho, mas é muito útil por exemplo se quisermos ordernar posts, buscando por determinada categoria (queremos que sejam listados os últimos cadastrados) e também em outras situações que se precisa ordenar os resultados de forma crescente ou decrescente. </p>
<p>Se utilizarmos a view que emite apenas o estado como chave (by_state), o CouchDB vai ordenar as cidades pelo <strong>id</strong> (no caso o id é o nome da cidade) então teríamos as cidades do determinado estado, ordenadas alfabeticamente. Então, precisamos criar uma view que emita um array (estado e data de criação) como chave.<br />
Acrescente na classe</p>
<pre class="brush: ruby;">
view_by :state, :created_at
</pre>
<p>Será criada a seguinte view</p>
<pre class="brush: jscript;">
function(doc) {
  if ((doc['couchrest-type'] == 'City') &amp;&amp; doc['state'] &amp;&amp; doc['created_at']) {
    emit([doc['state'], doc['created_at']], null);
  }
}
</pre>
<p>Buscando as cidades (cadastradas primeiro) do estado SP</p>
<pre class="brush: ruby;">
City.by_state_and_created_at(:startkey =&gt; ['SP'], :endkey =&gt; ['SP', {}])
</pre>
<p>Repare que a cidade de Sorocaba vem primeiro (pois foi cadastrada primeiro), se tivéssemos utilizado a view que emite como chave apenas o estado, São Paulo viria primeiro</p>
<pre class="brush: jscript;">
{&quot;total_rows&quot;:3,&quot;offset&quot;:1,&quot;rows&quot;:[
  {&quot;id&quot;:&quot;sorocaba&quot;,&quot;key&quot;:[&quot;SP&quot;,&quot;2010/05/25 01:25:53 +0000&quot;],&quot;value&quot;:null},
  {&quot;id&quot;:&quot;sao-paulo&quot;,&quot;key&quot;:[&quot;SP&quot;,&quot;2010/05/25 01:25:54 +0000&quot;],&quot;value&quot;:null}
]}
</pre>
<p>Podemos concluir que as views do CouchDB são <strong>extremamente poderosas e simples</strong>, de início parece complicado, já que estamos habituados ao SQL, porém quando se entende bem o conceito do <strong>Map/Reduce</strong> as coisas ficam bem mais fáceis. No próximo post pretendo escrever sobre agrupamentos (<a href="http://www.p3m.com.br/blog/group-by-no-couchdb/" target="_blank">GROUP BY</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/order-by-no-couchdb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CouchRest ExtendedDocument &#8211; Queries Básicas</title>
		<link>http://www.p3m.com.br/blog/couchrest-extendeddocument-queries-basicas/</link>
		<comments>http://www.p3m.com.br/blog/couchrest-extendeddocument-queries-basicas/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 02:52:43 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[couchrest]]></category>
		<category><![CDATA[queries couchdb]]></category>
		<category><![CDATA[views couchdb]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=156</guid>
		<description><![CDATA[Em ruby temos algumas gems para serem utilizadas com o CouchDB. Particularmente eu prefiro a gem CouchRest, construída pelos commiters do CouchDB (Chris Anderson é um deles). E um dos commiters do CouchRest (que vem fazendo um excelente trabalho) é o Marcos Tapajos da Improve IT e RedeParede. Para saber mais como instalar e utilizar [...]]]></description>
			<content:encoded><![CDATA[<p>Em ruby temos algumas gems para serem utilizadas com o <a href="http://www.p3m.com.br/blog/couchdb/" target="_blank">CouchDB</a>. Particularmente eu prefiro a gem <a rel="nofollow" href="http://github.com/couchrest/couchrest" target="_blank">CouchRest</a>, construída pelos commiters do CouchDB (<a rel="nofollow" href="http://twitter.com/jchris" target="_blank">Chris Anderson</a> é um deles). E um dos commiters do CouchRest (que vem fazendo um excelente trabalho) é o <a rel="nofollow" href="http://tapajos.me/" target="_blank">Marcos Tapajos</a> da Improve IT e RedeParede.<br />
Para saber mais como instalar e utilizar o CouchRest acesse a <a rel="nofollow" href="http://wiki.github.com/couchrest/couchrest/" target="_blank">wiki</a> no Github.</p>
<p>Vamos considerar a seguinte classe (Post) que herda <strong>ExtendedDocument</strong> da gem CouchRest</p>
<pre class="brush: ruby;">
class Post &lt; CouchRest::ExtendedDocument
  use_database DB #constante com as infos do seu banco

  property :titulo
  property :conteudo

  #será criado no banco uma view pelo título
  view_by :titulo

end
</pre>
<p>Carregando todos os documentos com o &#8220;couchrest-type&#8221; Post</p>
<pre class="brush: ruby;">
@posts = Post.all
puts @posts.inspect
</pre>
<p>Carregando um documento pelo ID</p>
<pre class="brush: ruby;">
#Sem excessões caso o documento não seja encontrado
@post = Post.get(&quot;id_do_documento&quot;)
puts @post.inspect

#Será gerado uma excessão se o documento não for encontrado
@post = Post.get!(&quot;id_do_documento&quot;)
puts @post.inspect
</pre>
<p><strong>Utilizando Views</strong></p>
<p>A view criada pelo CouchRest</p>
<pre class="brush: jscript;">
function(doc) {
  if ((doc['couchrest-type'] == 'Post') &amp;&amp; doc['titulo']) {
    emit(doc['titulo'], null);
  }
}
</pre>
<pre class="brush: ruby;">
#Carregando todos do documentos com &quot;couchrest-type&quot; Post e que tenham um título
@posts = Post.by_titulo
puts &quot;O número de posts encontrados foi #{@posts.count}&quot;
puts
puts @posts.inspect

#Carregando todos do documentos com &quot;couchrest-type&quot; Post e um título específico
@posts = Post.by_titulo(:key =&gt; &quot;Um título em específico&quot;)
puts @posts.inspect
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/couchrest-extendeddocument-queries-basicas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CouchDB 0.11.0</title>
		<link>http://www.p3m.com.br/blog/couchdb-0-11-0/</link>
		<comments>http://www.p3m.com.br/blog/couchdb-0-11-0/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 13:16:36 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[couchdb 0.11]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=154</guid>
		<description><![CDATA[Ontem foi lançada a versão 0.11 do CouchDB que é a base antes da versão 1.0. Algumas das melhorias foram: Adicionado suporte a instalador Windows Melhora nas views Correção de bugs na construção de views Melhorias nos cálculos de estatísticas Melhorias de velocidade e concorrência em pesquisas Corrigido timeout de HTTP para replicação Melhorias no [...]]]></description>
			<content:encoded><![CDATA[<p>Ontem foi lançada a versão 0.11 do <a title="CouchDB" href="http://www.p3m.com.br/blog/couchdb/" target="_blank">CouchDB</a> que é a base antes da versão 1.0.<br />
Algumas das melhorias foram:</p>
<p>Adicionado suporte a instalador Windows<br />
Melhora nas views<br />
Correção de bugs na construção de views<br />
Melhorias nos cálculos de estatísticas<br />
Melhorias de velocidade e concorrência em pesquisas<br />
Corrigido timeout de HTTP para replicação<br />
Melhorias no Futon UI<br />
Melhorias nos anexos (attachments)<br />
Melhorias na autenticação<br />
Adicionado um manipular de reescrita de url<br />
Adicionado um manipulador de atenticação de proxy<br />
Adicionado habilidade de replicar documentos pelo ID<br />
Adicionado a criação de virtual hosts</p>
<p>São muitas as melhorias que a equipe do CouchDB vem realizando, com certeza o projeto está bem próximo da maturidade para a versão 1.0</p>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/couchdb-0-11-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compactar banco de dados &#8211; CouchDB</title>
		<link>http://www.p3m.com.br/blog/compactar-banco-de-dados-couchdb/</link>
		<comments>http://www.p3m.com.br/blog/compactar-banco-de-dados-couchdb/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 16:17:51 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[compactar couchdb]]></category>
		<category><![CDATA[mvcc]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=134</guid>
		<description><![CDATA[O CouchDB assim como alguns bancos relacionais (MySQL, Postgre, Oracle etc) utiliza o modelo MVCC (Multiversion concurrency control), então quando um documento recebe uma atualização, é criada uma nova versão do documento. Devido ao fato da criação de novas versões, seu banco de dados pode começar a crescer exponencialmente. Então você pode compactar o banco, [...]]]></description>
			<content:encoded><![CDATA[<p>O CouchDB assim como alguns bancos relacionais (MySQL, Postgre, Oracle etc) utiliza o modelo MVCC (Multiversion concurrency control), então quando um documento recebe uma atualização, é criada uma nova versão do documento.</p>
<p>Devido ao fato da criação de novas versões, seu banco de dados pode começar a crescer exponencialmente. Então você pode compactar o banco, para economizar certo espaço em disco. A compactação comprimi o arquivo de banco de dados removendo seções não utilizadas que foram criadas durante as atualizações.</p>
<p>A compactação pode ser feita enviando uma requisição HTTP Post para o &#8220;sub recurso&#8221; <em>_compact</em> do seu banco. Em caso de sucesso um status HTTP 202 é retornado.</p>
<pre class="brush: bash;">
curl -X POST http://localhost:5984/meu_banco/_compact
#=&gt; {&quot;ok&quot;:true}
</pre>
<p>Você pode verificar informações sobre sua base (inclusive se uma compactação está ocorrendo) enviando uma requisição HTTP Get ao banco.</p>
<pre class="brush: bash;">
curl -X GET http://localhost:5984/meu_banco
#=&gt; {&quot;db_name&quot;:&quot;meu_banco&quot;, &quot;doc_count&quot;:334, &quot;doc_del_count&quot;:0, &quot;update_seq&quot;:5329, &quot;purge_seq&quot;:0, &quot;compact_running&quot;:false, &quot;disk_size&quot;:614498, &quot;instance_start_time&quot;:&quot;1267717198892433&quot;, &quot;disk_format_version&quot;:4}
</pre>
<p>É recomendado que a compactação seja feita em um horário em que o CouchDB não receba muitas escritas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/compactar-banco-de-dados-couchdb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Autenticar usuário no CouchDB</title>
		<link>http://www.p3m.com.br/blog/autenticar-usuario-no-couchdb/</link>
		<comments>http://www.p3m.com.br/blog/autenticar-usuario-no-couchdb/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 22:01:34 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[autenticar usuario couchdb]]></category>
		<category><![CDATA[configurar usuario couchdb]]></category>
		<category><![CDATA[couchrest]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=127</guid>
		<description><![CDATA[Por padrão o CouchDB não exige que seja configurado uma conta com usuário e senha, porém criar uma conta é simples. Para criar uma conta edite o arquivo local.ini sudo vim /usr/local/etc/couchdb/local.ini Altere require_valid_user para true na sessão couch_httpd_auth [couch_httpd_auth] require_valid_user = true Acrescente o usuário e senha na sessão admins [admins] admin = senha_admin [...]]]></description>
			<content:encoded><![CDATA[<p>Por padrão o CouchDB não exige que seja configurado uma conta com usuário e senha, porém criar uma conta é simples.<br />
Para criar uma conta edite o arquivo <em>local.ini</em>
<pre class="brush: bash;">
sudo vim /usr/local/etc/couchdb/local.ini
</pre>
<p>Altere <strong>require_valid_user</strong> para true na sessão <em>couch_httpd_auth</em></p>
<pre class="brush: plain;">
[couch_httpd_auth]
require_valid_user = true
</pre>
<p>Acrescente o usuário e senha na sessão <em>admins</em></p>
<pre class="brush: plain;">
[admins]
admin = senha_admin
</pre>
<p>Reinicie o CouchDB</p>
<pre class="brush: bash;">
sudo /usr/local/etc/init.d/couchdb restart
</pre>
<p>O CouchDB irá criar um hash com a senha:</p>
<pre class="brush: plain;">
[admins]
admin = -hashed-c3574aef8a2969b53a8c33edf28cb538d997397c,51e3cce80f8e 809804cfcbe481263bf5
</pre>
<p>Se você estiver programando em ruby e utilizando a gem <a href="http://github.com/couchrest/couchrest" rel="nofollow" target="_blank">couchrest</a>, você pode fazer a conexão assim:</p>
<pre class="brush: ruby;">
CouchRest.database!(&quot;http://admin:senha_admin@127.0.0.1:5984/base_de_dados&quot;)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/autenticar-usuario-no-couchdb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CouchDB &#8211; Implementação</title>
		<link>http://www.p3m.com.br/blog/couchdb-implementacao/</link>
		<comments>http://www.p3m.com.br/blog/couchdb-implementacao/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 02:36:08 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[banco de dados orientados a documentos]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[lock free]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=114</guid>
		<description><![CDATA[O CouchDB é feito na plataforma Erlang OTP, uma linguagem de programação funcional, concorrente e uma plataforma de desenvolvimento. Erlang foi desenvolvida para aplicações em tempo real de telecomunicações com ênfase na extrema confiabilidade e disponibilidade. Na sintaxe e na semântica, Erlang é muito diferente de linguagens de programação convencionais como C ou Java. Erlang [...]]]></description>
			<content:encoded><![CDATA[<p>O <a href="http://www.p3m.com.br/blog/couchdb/" target="_blank">CouchDB</a> é feito na <a rel="nofollow" href="http://www.erlang.org/" target="_blank">plataforma Erlang OTP</a>, uma linguagem de programação funcional, concorrente e uma plataforma de desenvolvimento. Erlang foi desenvolvida para aplicações em tempo real de telecomunicações com ênfase na extrema confiabilidade e disponibilidade.</p>
<p>Na sintaxe e na semântica, Erlang é muito diferente de linguagens de programação convencionais como C ou Java. Erlang usa &#8220;processos&#8221; leves e passagem de mensagem por concorrência, não tem compartilhamento de estado de thread e todos os dados são imutáveis. A natureza robusta e concorrente do Erlang é ideal para um servidor de banco de dados.</p>
<p>O CouchDB é projetado para concorrência livre de locks, no modelo conceitual e na implementação atual do Erlang. Reduzindo gargalos e evitando locks mantém o sistema inteiro funcionando previsivelmente sobre cargas pesadas. O CouchDB pode acomodar muitas mudanças de replicação de clientes, abrir e atualizar documentos, consultar views cujos índices estão sendo simultaneamente sendo atualizados por outros clientes, sem precisar de locks.</p>
<p>Para alta disponibilidade e mais usuários concorrentes, o Couchdb é projetado para um cluster &#8220;shared nothing&#8221;. Em um cluster &#8220;shared nothing&#8221;, cada máquina é independente e replica dados com seus companheiros de cluster, deixando falhas individuas de servidores com zero de downtime. E porque scans de consistência e consertos não são necessários no restart, se o cluster inteiro falhar &#8211; devido a uma queda de energia no datacenter, por exemplo &#8211; todo o sistema distribuído do CouchDB volta a ficar disponível depois de um restart.</p>
<p>O CouchDB é construído desde o início com uma visão consistente de um sistema distribuído de banco de dados orientado a documento. Ao contrário de tentativas pesadas em construir recursos distribuídos no topo da mesma herança de modelos e base de dados, ele é o resultado de um projeto, engenharia e integração cuidadosos. O documento, view, segurança e modelos de replicação, a proposta especial da linguagem de query, o layout robusto e eficiente de disco e a natureza concorrente e real da plataforma Erlang são cuidadosamente integrados para um sistema real e eficiente.</p>
<p>Essa é uma tradução adaptada:<br />
<a rel="nofollow" href="http://couchdb.apache.org/docs/overview.html" target="_blank">http://couchdb.apache.org/docs/overview.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/couchdb-implementacao/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CouchDB Views &#8211; exemplo prático</title>
		<link>http://www.p3m.com.br/blog/couchdb-views-exemplo-pratico/</link>
		<comments>http://www.p3m.com.br/blog/couchdb-views-exemplo-pratico/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 16:25:06 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[reduce]]></category>
		<category><![CDATA[select couchdb]]></category>
		<category><![CDATA[views couchdb]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=73</guid>
		<description><![CDATA[O CouchDB possui uma interface web (melhor que um phpmyadmin por exemplo) para administração dos dados, chamada Futon. Para acessá-la abra em seu browser: http://localhost:5984/_utils/ Vamos iniciar com um exemplo bem simples de como utilizar views. As views são usadas para recuperar os dados do banco. De início talvez pareça um pouco complicado, a maioria [...]]]></description>
			<content:encoded><![CDATA[<p>O CouchDB possui uma interface web (melhor que um phpmyadmin por exemplo) para administração dos dados, chamada Futon. Para acessá-la abra em seu browser:</p>
<p><a rel="nofollow" href="http://localhost:5984/_utils/" target="_blank">http://localhost:5984/_utils/</a></p>
<p>Vamos iniciar com um exemplo bem simples de como utilizar views.<br />
As <a href="http://www.p3m.com.br/blog/views-no-couchdb/" target="_blank">views</a> são usadas para recuperar os dados do banco. De início talvez pareça um pouco complicado, a maioria de nós está completamente adaptada ao SQL, mas aos poucos vamos mudando nossa forma de pensar (até mesmo quebrando a forma &#8220;relacional&#8221; de armazenamento dos dados) e vamos aprendendo conceitos interessantes, como <a rel="nofollow" href="http://en.wikipedia.org/wiki/MapReduce" target="_blank">Map/Reduce</a>.</p>
<p>Vamos supor que precisamos armazenar dados de estudantes (nome e idade apenas). Nos bancos relacionais teríamos que criar uma tabela &#8220;estudantes&#8221; com os devidos campos e tipos. Isso pode não ser tão bom, já que nem todos os estudantes podem ter as mesmas informações (representação dos dados). Os documentos são bem melhores para representarmos os elementos da vida real, do que as tabelas, são extremamente flexíveis. No CouchDB o documento (JSON) ficaria mais ou menos assim:</p>
<p><img class="aligncenter size-full wp-image-78" title="doc" src="http://www.p3m.com.br/blog/wp-content/uploads/2010/01/doc2.png" alt="" width="500" height="182" /></p>
<p>Um detalhe para o atributo type (que eu criei) para &#8220;informar&#8221; qual o tipo de documento, no caso se refere a estudantes.</p>
<p>Vamos supor que teríamos outros documentos no banco (de outros &#8220;types&#8221; também) e que gostaríamos de selecionar apenas as informações de estudantes. Em SQL seria:</p>
<pre class="brush: sql;">
SELECT * FROM students
</pre>
<p>No CouchDB poderíamos criar uma view (em javascript) assim:</p>
<pre class="brush: jscript;">
function(doc) {
  if(doc['type'] == 'Student') {
    emit(doc['name'], doc);
  }
}
</pre>
<p>Detalhe que essa é uma função do tipo Map. Serão selecionados apenas os documentos com type igual a &#8220;Student&#8221; e a chave é o nome do estudante.</p>
<p><img class="aligncenter size-full wp-image-80" title="view-lucas" src="http://www.p3m.com.br/blog/wp-content/uploads/2010/01/view-lucas.png" alt="" width="500" height="246" /></p>
<p>Existe uma série de vantagens em utilizar o conceito de Map/Reduce, principalmente quando se trata de aplicações que rodam em <a href="http://pt.wikipedia.org/wiki/Cluster" rel="nofollow" target="_blank">clusters</a>.<br />
Você também pode ler como funcionam os <a href="http://www.p3m.com.br/blog/view-indexes/" target="_blank">índices de views</a> no Couch.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/couchdb-views-exemplo-pratico/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>View Indexes</title>
		<link>http://www.p3m.com.br/blog/view-indexes/</link>
		<comments>http://www.p3m.com.br/blog/view-indexes/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 18:59:07 +0000</pubDate>
		<dc:creator>Lucas Renan</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[índices couchdb]]></category>
		<category><![CDATA[view indexes]]></category>
		<category><![CDATA[views couchdb]]></category>
		<category><![CDATA[views no couchdb]]></category>

		<guid isPermaLink="false">http://www.p3m.com.br/blog/?p=61</guid>
		<description><![CDATA[Antes de começar com a tradução sobre os índices de views do CouchDB, quero fazer um agradecimento especial ao Marcos Tapajós pela divulgação em CouchDB para brasileiros. O Tapajós trabalha para o Redeparede, para a Improve It e é commiter da gem CouchRest. Valeu Tapajós =] Índices de views As views são representações dinâmicas do [...]]]></description>
			<content:encoded><![CDATA[<p>Antes de começar com a tradução sobre os índices de views do CouchDB, quero fazer um agradecimento especial ao <a href="http://tapajos.me" target="_blank" rel="nofollow">Marcos Tapajós</a> pela divulgação em <a href="http://tapajos.me/2010/01/13/couchdb-para-brasileiros" target="_blank" rel="nofollow">CouchDB para brasileiros</a>. O Tapajós trabalha para o Redeparede, para a Improve It e é commiter da gem <a href="http://github.com/couchrest/couchrest" target="_blank" rel="nofollow">CouchRest</a>. Valeu Tapajós =]</p>
<p><strong>Índices de views</strong></p>
<p>As views são representações dinâmicas do conteúdo atual dos documentos de um banco de dados, e o CouchDB faz ser simples a criação de views úteis dos dados. Mas gerar uma view de um banco de dados com centenas de milhares ou milhões de documentos leva tempo e consome recursos, não é algo que o sistema deve fazer do zero toda hora.</p>
<p>Para manter a exibição de consultas rápida, a view engine mantém índices dessas views, e atualiza-os incrementalmente para refletir as mudanças no banco de dados. O design do core do CouchDB é largamente otimizado para criação eficiente de views e seus índices.</p>
<p>Visões e suas funções são definidas dentro de documentos especiais de &#8220;design&#8221; e um documento de design pode conter várias funções de views (unicamente nomeadas). Quando um usuário abre uma view e seu índice é automaticamente atualizado, todas as views no mesmo documento de design são indexadas em um único grupo.</p>
<p>O construtor de views usa o ID de sequência do banco de dados para determinar se um grupo de views está totalmente atualizado com o banco de dados. Se não, a view engine examina todos os documentos do banco (embalados em ordem sequencial) mudados desde a última atualização. Os documentos são lidos na ordem em que estão os arquivos no disco, reduzindo a frequência e custo de buscas no disco.</p>
<p>As views podem ser lidas e consultadas simultaneamente enquanto estão também sendo atualizadas. Se um cliente está recebendo o conteúdo de uma view grande, a mesma view pode ser aberta e atualizada concorrentemente por outro cliente sem bloquear o primeiro cliente. Isso é verdade para qualquer número de leituras de clientes simultâneos, que podem ler e consultar a view enquanto o índice está concorrentemente sendo atualizado por outros clientes sem causar problemas para os leitores.</p>
<p>Assim os documentos são examinados, os seus valores de linha anterior são removidos dos índices de views, se existirem. Se o documento for selecionado por uma função de view, os resultados da função são inseridos na view como uma nova linha.</p>
<p>Quando as mudanças nos índices de views são escritas no disco, as atualizações são sempre anexadas ao fim do arquivo, servindo tanto para reduzir as buscas no disco durante commits e para garantir que crashes e falhas de falta de energia não corrompam os índices. Se uma falha ocorrer durante uma atualização de um índice, a atualização incompleta do índice é simplesmente perdida e reconstruída incrementalmente a partir do seu estado anterior.</p>
<p>Essa é uma tradução adaptada:<br />
<a href="http://couchdb.apache.org/docs/overview.html" rel="nofollow" target="_blank">http://couchdb.apache.org/docs/overview.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.p3m.com.br/blog/view-indexes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
