[Este blog foi distribuído pelo site http://blog.grallandco.com].

Introdução

Os desenvolvedores sempre me perguntam como "versionar" documentos com o Couchbase 2.0. A resposta curta é: os clientes e o servidor não expõem esse recurso, mas ele é muito fácil de implementar.
Neste artigo, usarei uma abordagem básica, que poderá ser ampliada dependendo de seus requisitos comerciais.

Design

A primeira coisa a fazer é selecionar como "armazenar/organizar" as versões do seu documento, e para isso você tem diferentes designs:
  • copiar as versões do documento em novos documentos
  • copiar as versões do documento em uma lista de documentos incorporados
  • armazenar a lista de atributos que foram alterados em um elemento incorporado (ou novos documentos)
  • armazenar o "delta"
  • ...
Você terá de escolher o design com base nos requisitos do seu aplicativo (lógica comercial, tamanho do conjunto de dados, etc.). Para este artigo, vamos usar uma das abordagens mais simplistas: criar um novo documento para cada versão com as seguintes regras para as chaves:
  1. A versão atual é uma simples chave/documento, sem alterações na chave.
  2. A versão é uma cópia do documento, e o número da versão é adicionado à chave.
Isso se parece com:
Versão atual   minha chave
Versão 1   mykey::v1
Versão 2   mykey::v2
     …

Com essa abordagem, os aplicativos existentes sempre usarão a versão atual do documento, pois a chave não é alterada. Mas essa abordagem cria novos documentos que serão indexados pelas exibições existentes.

Por exemplo, no aplicativo Beer Sample, a visualização a seguir é usada para listar a cerveja por nome:

function (doc, meta) {
if(doc.type && doc.type == "beer") {
emit(doc.name);
}
}

É muito simples "suportar" o controle de versão sem afetar o código existente, exceto a própria exibição. A nova exibição precisa emitir chaves e valores somente para a versão atual do documento. Este é o código da nova exibição:

function (doc, meta) {
if(doc.type && doc.type == "beer" && (meta.id).indexOf("::v") == -1 ) {
emit(doc.name);
}
}
Com essa alteração, os aplicativos existentes que estão usando essa visualização continuarão a funcionar com o mesmo comportamento.

Implementação do controle de versão

Com base nesse design, quando o aplicativo precisar fazer a versão do documento, deverá ocorrer a seguinte lógica:
  1. Obter a versão atual do documento
  2. Aumentar o número da versão (por exemplo, usando outra chave que mantém o número da versão para cada documento)
  3. Crie a versão com a nova chave "mykey::v1"
  4. Salvar a versão atual do documento
Vamos dar uma olhada no código em Java
  Objeto obj = client.get(key);
Se (obj != null) {
// obter a próxima versão, criar ou usar a chave: mykey_version
long version = client.incr(key + "_version", 1, 1);
String keyForVersion = key + "::v" + version; // mykey::v1
tente {
client.set(keyForVersion, obj).get();
} catch (Exception e) {
logger.severe("Cannot save version "+ version + " for key "+ key +" - Error: "+ e.getMessage() );
}
}
client.set(key, value);

Bastante simples, não é?

O aplicativo pode acessar o documento usando a chave, mas também pode obter uma versão ou a lista de todas as versões; esse é um dos motivos pelos quais é interessante criar uma chave (mykey_version) e use-o também para excluir documentos e versões relacionadas.

Com base no comentário anterior, a operação de exclusão tem a seguinte aparência:

  Objeto obj = client.get(key);
// precisa excluir toda a versão primeiro
Objeto vObject = this.get(key + "_version");
Se (vObject != null) {
long biggerVersion = Long.parseLong((String) vObject);
tente {
// excluir todas as versões
for (int i = 1; i <= biggerVersion; i++) {
String versionKey = key + "::v" + i;
client.delete(versionKey).get();
}
// excluir o contador
client.delete(key + "_version").get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
client.delete(key);

 

Usar controle de versão

Como exemplo, criei uma pequena biblioteca disponível no GitHub https://github.com/tgrall/couchbase-how-to-versioningComo já foi dito, essa biblioteca estende o cliente do Couchbase e substitui algumas das operações: set, replace e delete. (o básico: sem TLL, sem durabilidade) Como eu disse antes, este é apenas um exemplo.
Criação e instalação 
git clone https://github.com/tgrall/couchbase-how-to-versioning.git
cd how-to-versioning
mvn instalação limpa
Em seguida, adicione essa biblioteca ao seu projeto, além do cliente Java do Couchbase, por exemplo, em seu pom.xml

com.couchbase.howtos
couchbase-como-fazer-versões
1.0-SNAPSHOT

couchbase
cliente couchbase
1.1.8

Codifique seu aplicativo

Crie um documento e faça uma versão dele:

 List uris = new LinkedList();
uris.add(URI.create("http://127.0.0.1:8091/pools"));
CouchbaseClientWithVersioning client = null
tente {
cliente = new CouchbaseClientWithVersioning(uris, "default", "");
String key = "key-001";
client.set(key, "This is the original version");
System.out.printf("Original '%s' .n", client.get(key));
client.set(key, "This is a new version", true); // criar uma nova versão
System.out.printf("Versão atual '%s' .n", client.get(key));
System.out.printf("Versão 1 '%s' .n", client.get(key, 1));
client.set(key, "This is another version", true); // criar uma nova versão
System.out.printf("Todas as versões %s .n", client.getAllVersions(key));
client.deleteVersion(key, 1); // criar uma nova versão
System.out.printf("Todas as versões %s (após excluir 1 versão).n", client.getAllVersions(key));
client.delete(key); // criar uma nova versão
System.out.printf("Todas as versões %s (após excluir a chave principal).n", client.getAllVersions(key));
} catch (Exception e) {
e.printStackTrace();
}
Se (cliente !=nulo) {
cliente.shutdown();
}

Explicação rápida:

  • Linha 5: em vez de usar o Cliente Couchbaseo aplicativo usa a extensão  CouchbaseClientWithVersioning classe.
  • Linha 7: criar uma nova entrada
  • Linha 9: criar uma nova versão, o valor booleano para "true" força o controle de versão do documento
  • O aplicativo usa outros métodos, como obter uma versão específica (linha 11), obter todas as versões (linha 13), excluir uma versão específica (linha 14) e, finalmente, excluir a chave e todas as versões (linha 16).
Portanto, usando essa abordagem, o desenvolvedor controla explicitamente quando criar uma versão, já que ele precisa adicionar o parâmetro booleano na operação de definição. Nessa pequena biblioteca de exemplo, também é possível fazer o controle de versão automático; nesse caso, todas as chamadas de set e replace criarão uma versão; para isso, o desenvolvedor só precisa chamar o método setAutoVersioning(true). Algo como:
    cliente = new CouchbaseClientWithVersioning(uris, "default", "");
client.setAutomaticVersionning(true);

 

Com essa abordagem, você pode fornecer controle de versão ao seu aplicativo com alterações mínimas no código. Você pode testá-lo no aplicativo Beer Sample, mas não se esqueça de alterar as exibições conforme o documentador acima para que retornem apenas atual versão dos documentos.

Conclusão

Como você pode ver, fazer o controle de versão no Couchbase não é tão complicado, mas é algo que deve ser feito pelo seu aplicativo com base em seus requisitos e restrições. Você tem muitas soluções diferentes e nenhuma dessas opções é perfeita para todos os casos de uso.

Neste código de exemplo específico, estou trabalhando com um design simples em que crio uma cópia dos documentos para cada versão. Com essa abordagem, também é interessante mencionar que você pode versionar "qualquer coisa", não apenas o documento JSON, mas também quaisquer valores. Como eu disse antes, essa é uma abordagem possível e, como qualquer design, ela tem algum impacto sobre o aplicativo ou o banco de dados, neste caso, principalmente sobre o banco de dados:

  • Aumentar o número de chaves e documentos
  • Dobrar - ou mais - o número de operações, por exemplo, ao atualizar um documento, o aplicativo precisa obter o valor atual, criar uma versão e salvar a versão atual.
  • Gerenciamento de consistência ao adicionar uma nova versão e incrementar o número da versão (é necessário lidar com erros ao criar uma nova versão, excluir as versões e contrair....)
Muitos recursos poderiam ser adicionados a isso facilmente, por exemplo:
  • Limite para um número específico de versões,
  • Habilitar o controle de versão somente da operação replace()
  • Adicionar atributo específico sobre versões no documento JSON (por exemplo, data da versão)
  • ….

Se você estiver usando o controle de versão em seu aplicativo Couchbase, sinta-se à vontade para comentar ou escrever um pequeno artigo que descreva a maneira como você está fazendo isso.

Autor

Postado por A equipe do Couchbase

Jennifer Garcia é gerente sênior de Web na Couchbase Inc. Como gerente do site, Jennifer tem a responsabilidade geral pelas propriedades do site, incluindo design, implementação, conteúdo e desempenho.

Deixar uma resposta