A biblioteca do cliente Couchbase 1.2-Beta inclui uma nova API para o gerenciamento básico de clusters. Há métodos para criar, remover e listar buckets. Há métodos semelhantes para gerenciar documentos de design. Esses novos recursos são encontrados na nova classe CouchbaseCluster, nos termos do Couchbase.Management namespace. O principal benefício dessa nova API é que agora é possível permitir que seu aplicativo crie seu bucket e defina seus documentos de design quando for iniciado.
Uma das sobrecargas para a criação de novos documentos de design permite que você especifique um Fluxo como a origem do documento de design. Com essa versão, é fácil criar documentos de design a partir de um conjunto de arquivos. Você também pode simplesmente especificar uma string que contenha o documento.
Recentemente, tive a ideia de criar um utilitário de linha de comando simples para usar esses métodos de gerenciamento de documentos de design para automatizar a criação de exibições básicas. O resultado dessa ideia está no GitHub em https://github.com/jzablocki/couchbase-model-views. Usando essa estrutura, você poderá automatizar a criação de exibições simplesmente decorando suas classes de modelo existentes com atributos personalizados.
Considere um Cerveja com propriedades para Name, Description, Brewery e ABV.
público classe Cerveja
{
público string Id { obter; definir; }
público string Nome { obter; definir; }
público string Descrição { obter; definir; }
público flutuante ABV { obter; definir; }
público string Cervejaria { obter; definir; }
}
Essa classe mapeia os documentos "beer" em seu bucket do Couchbase.
"name" (nome): "Samuel Adams Summer Ale",
"abv": 5.2,
"tipo": "cerveja",
"brewery_id": "110f04db06",
"description" (descrição): "Brilhante e cítrico, fabricado com grãos misteriosos de...
}
Para obter esse mapeamento, você provavelmente usaria Newtonsoft.Jsondo usuário.
público classe Cerveja
{
público string Id { obter; definir; }
[JsonProperty("name" (nome))]
público string Nome { obter; definir; }
[JsonProperty("description" (descrição))]
público string Descrição { obter; definir; }
[JsonProperty("abv")]
público flutuante ABV { obter; definir; }
[JsonProperty("breweryId")]
público string Cervejaria { obter; definir; }
}
Usando dois novos atributos encontrados no CouchbaseModelViews.Framework você pode decorar ainda mais essa classe para declarar quais propriedades dessa classe devem ser indexadas pelo Couchbase Server. Esses atributos são CouchbaseDesignDocument e Chave do CouchbaseView.
[CouchbaseDesignDoc("cervejas", "cerveja")]
público classe Cerveja
{
público string Id { obter; definir; }
[JsonProperty("name" (nome))]
[Chave do CouchbaseView("by_abv_and_name", "name" (nome), 1)]
[Chave do CouchbaseView("by_name", "name" (nome))]
público string Nome { obter; definir; }
[JsonProperty("description" (descrição))]
público string Descrição { obter; definir; }
[JsonProperty("abv")]
[Chave do CouchbaseView("by_abv_and_name", "abv", 0)]
público flutuante ABV { obter; definir; }
[JsonProperty("breweryId")]
[Chave do CouchbaseView("by_brewery" (por cervejaria), "breweryId")]
público string Cervejaria { obter; definir; }
}
O CouchbaseDesignDoc é definido em uma classe de modelo. Ele usa um objeto plain-old-CLR (POCO) para definir um documento de design. Se você omitir o argumento name, será criado um documento de design com o mesmo nome (em letras minúsculas) da classe. Se você omitir o argumento type, as exibições verificarão se os documentos têm uma propriedade type com o valor do nome (em minúsculas) da classe.
O Chave do CouchbaseView é definido nas propriedades em uma classe POCO que deve ser indexada. Por exemplo, a propriedade Name na classe Cerveja acima tem uma classe Chave do CouchbaseView nele com os argumentos "by_name" e "name". A visualização que resultará desses valores é a seguinte:
se (doc.tipo == "cerveja" && doc.nome) {
emitir(doc.nome, nulo);
}
}
O argumento "by_name" é o nome dessa exibição e o argumento "name" define qual propriedade é verificada quanto à existência e emitida.
Também é possível incluir chaves compostas decorando várias propriedades com Chave do CouchbaseView contendo o mesmo valor para o parâmetro viewName. As chaves compostas são demonstradas com "by_abv_and_name" nas propriedades ABV e Name. Observe também que há um parâmetro de ordem opcional que permite definir a ordem em que as propriedades são emitidas.
se (doc.tipo == "cerveja" && doc.abv && doc.nome) {
emitir([doc.abv, doc.nome], nulo);
}
}
Depois de decorar sua classe com os atributos apropriados, você pode usar a função Gerador de visualizações do CouchbaseModel para executar os modelos por meio do gerador de exibições. Esse é um projeto simples de linha de comando que requer um app.config com uma seção que liste todos os assemblies que contêm modelos que serão usados para criar exibições.
<sectionGroup nome="modelViews">
<seção nome="assembléias" tipo="System.Configuration.DictionarySectionHandler"/>
>
<modelViews>
<assemblies>
<add chave="DemoModels" valor="CouchbaseModelViews.DemoModels" />
>
>
Além disso, você precisará configurar o CouchbaseCluster. CouchbaseCluster estão sendo criadas usando a mesma configuração (código ou app.config) que as instâncias existentes do Cliente Couchbase. No entanto, agora há mais duas propriedades que você pode definir para fornecer as credenciais de administrador.
<servidores balde="default" bucketPassword=“” nome de usuário="Administrador" senha="qwerty">
<add uri="http://localhost:8091/pools" />
>
>
Depois de configurar o app.config, verifique se os assemblies listados estão no diretório bin, onde podem ser carregados. A maneira mais fácil de obter essa capacidade de descoberta é, obviamente, fazer referência a eles. Entretanto, se quiser usar apenas uma versão compilada do aplicativo de console, basta copiá-los para o diretório bin.
Quando executada, a estrutura criará um documento de design "beers" que se parece com o seguinte:
"visualizações": {
"by_abv_and_name": {
"mapa": "function(doc, meta) { rnt Se (doc.type == “cerveja“ && doc.abv && doc.name) { rntt emit([doc.abv, doc.name], null); rnt } rn }”
},
"by_name": {
"mapa": "function(doc, meta) { rnt Se (doc.type == “cerveja“ && doc.name) { rntt emit(doc.name, null); rnt } rn }”
},
"by_brewery" (por cervejaria): {
"mapa": "function(doc, meta) { rnt Se (doc.type == “cerveja“ && doc.breweryId) { rntt emit(doc.breweryId, null); rnt } rn }”
}
}
}
O console não contém nenhuma lógica de criação de exibição real. Ele apenas orquestra chamadas para os vários componentes de encanamento dentro do Estrutura projeto. Se preferir incluir a criação da visualização dentro do Global.asax ou de algum outro evento de início do aplicativo, você mesmo poderá fazer essas chamadas. Há quatro componentes principais da estrutura.
- O ConfigParser simplesmente lê a lista de assemblies da seção de configuração e gera uma lista enumerável de assemblies.
- O ViewBuilder recebe um assembly ou uma lista enumerável de assemblies e itera sobre cada um dos tipos. Para cada tipo encontrado com um CouchbaseDesignDoc as visualizações são construídas. As Construir do método ViewBuilder retorna um dicionário, em que as chaves são os nomes dos documentos de design e os valores são os documentos de design reais.
- O DesignDocManager recebe um dicionário com o nome do documento, pares de documentos de design e usa o CouchbaseCluster para criar documentos de design.
- Há também um ViewRunner que executará as exibições recém-criadas.
var construtor = novo ViewBuilder();
construtor.AddAssemblies(montagens.ToList());
var designDocs = construtor.Construir();
var ddManager = novo DesignDocManager();
ddManager.Criar(designDocs, (s) => Console.WriteLine("Criado {0} documento de design", s));
var runner = novo ViewRunner();
corredor.Executar(designDocs, (k, v, s) => Console.WriteLine("[{0}::{1}] Key {2}", k, v, s["chave"]), 5);
Não há nenhum acoplamento entre dois desses três componentes e você pode usá-los como quiser. Se você tiver seu próprio recurso de coleta de montagem, por exemplo, basta passá-lo para o componente ViewBuilder.Build para renderizar o JSON necessário para criar as exibições.
Neste ponto, a estrutura está quase completa e razoavelmente testada. O código tem alguns loops a mais do que eu gostaria e talvez eu tenha usado Tuples em excesso, mas funciona. Sinta-se à vontade para usá-lo em seus projetos. Lembre-se de que este é um projeto do Couchbase Labs e não tem suporte oficial. Lembre-se também de que ele está usando a versão Beta da .NET Couchbase Client Library e que a API está sujeita a alterações.
Não entendo o conceito aqui. Como faço para salvar a nova visualização (documento de design do couchbase) no couchbase?
Oi Sam,
As novas exibições são salvas quando você executa o código abaixo (acima). Basicamente, você só precisa passar para o ViewBuilder um assembly que contenha classes marcadas com os novos atributos do Couchbase. Quando você chamar Create no DesignDocManager, ele criará as exibições.
var assemblies = ConfigParser.GetAssemblies();
var builder = new ViewBuilder();
builder.AddAssemblies(assemblies.ToList());
var designDocs = builder.Build();
var ddManager = new DesignDocManager();
ddManager.Create(designDocs);
E quanto a conectar-se ao servidor couchbase e salvar esse documento de design lá? É isso que estou confuso... Não deveríamos estar salvando isso no servidor couchbase?
O Ddmanager salva a visualização no couchbase? O que eu não entendo. Qual é a relação que esse código tem com o banco de dados? Como e onde a exibição é salva no bucket?
Existe alguma maneira de passar a conexão e as instâncias do objeto cliente por meio do código em vez de usar o arquivo de configuração ao salvar o documento de design?
Agradeceria se você pudesse me ajudar. Tentei seu código da seguinte forma:
objAssemblies.Add(System.Reflection.Assembly.GetAssembly(typeof(myclass))); //myclass tem todas as propriedades decoradas com atributos
builder.AddAssemblies(objAssemblies);
var designDocs = builder.Build();
var ddManager = new DesignDocManager();
ddManager.Create(designDocs);
Mas isso não funciona
Quero poder usar o GetView. Ele sempre me dá um erro 404. Tentei marcar todas as minhas classes de modelo com o CouchbaseDesignDoc e armazená-las no couchbase, mas parece que não funciona se eu usar o GetView... por favor, me ajude...
Oi Matt,
Você verificou se as exibições são criadas no servidor depois de executar o trecho de código do ViewBuilder/DesignDocManager acima?
- João
Faremos uma demonstração desse projeto em nosso Google Hangout hoje à tarde (siga o Couchbase no Google+ para obter informações). Depois, postarei um link aqui.
É bom, mas eu também gostaria de ver uma maneira de projetar os documentos de forma semelhante ao FluentNHibernate, em vez de documentos de design baseados em atribuições.