[Este blog foi distribuído pelo site http://blog.grallandco.com].
Introdução
Design
- 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"
- ...
- A versão atual é uma simples chave/documento, sem alterações na chave.
- A versão é uma cópia do documento, e o número da versão é adicionado à chave.
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:
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:
if(doc.type && doc.type == "beer" && (meta.id).indexOf("::v") == -1 ) {
emit(doc.name);
}
}
Implementação do controle de versão
- Obter a versão atual do documento
- Aumentar o número da versão (por exemplo, usando outra chave que mantém o número da versão para cada documento)
- Crie a versão com a nova chave "mykey::v1"
- Salvar a versão atual do documento
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:
// 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
cd how-to-versioning
mvn instalação limpa
…
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:
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).
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
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....)
- 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.