O que diferencia um armazenamento de documentos de um armazenamento de valores-chave?
Um banco de dados de documentos pode consultar e manipular o conteúdo do que armazena, enquanto o valor permanece um mistério opaco para o armazenamento de valores-chave.
Com o Couchbase Server 4.5, introduzimos nossa nova API de subdocumento para oferecer maior acesso de consulta e mutação à parte interna de seus documentos.
Noções básicas de subdocumentos
Então, qual é o resumo dos novos recursos de subdocumento do Couchbase?
- Recuperar partes de um documento.
- Altere partes de um documento enviando as alterações para o Couchbase Server.
- Disponível agora em todos os SDKs oficiais do Couchbase Server.
- Complementa a consulta oferecida pelas exibições e a consulta e as mutações oferecidas pelo N1QL.
Vamos ver o porquê.
Por que operações de subdocumentos?
Digamos que temos um documento JSON de 1 MB no Couchbase que armazena um registro de bate-papo entre duas pessoas. Cada vez que os participantes do bate-papo escrevem algo novo, queremos adicioná-lo ao documento de registro.
Sem operações de subdocumento, precisaríamos:
- buscar o documento inteiro
- desserialize-o em seu aplicativo
- adicionar a nova linha da conversa
- serializá-lo de volta para JSON
- enviar o documento completo de volta ao Couchbase para ser armazenado.
Usando o cliente Python do Couchbase, seria algo parecido com isto:
|
1 2 3 |
rv = cb.get('chatlog') # Get the entire document rv.doc.messages += ['nvm lol'] # Modify the doc locally cb.replace(rv.key, rv.doc, cas=rv.cas) # Upload entire document again |
Parece um grande desperdício. Agora considere a velocidade com que as pessoas tendem a conversar em mensagens instantâneas. Em seguida, pense em quantos bate-papos simultâneos poderiam estar ocorrendo.
O Couchbase Server pode desempenhar seu papel com prazer, mas sobrecarrega desnecessariamente a sua rede e faz com que você mantenha o código do aplicativo para lidar com o que você pode considerar razoavelmente como funções da camada de banco de dados.
Com as operações de subdocumento, podemos fazer muito menos. Adicionar uma nova linha a um registro de bate-papo seria mais ou menos assim, novamente em Python:
|
1 2 |
import couchbase.subdocument as SD cb.mutate_in('chatlog', SD.append('messages', 'nvm lol')) |
Enviamos a nova linha para o Couchbase Server, especificando o documento e em que parte do documento a alteração deve ser feita.
Dessa forma, evitamos uma viagem de ida e volta, economizamos largura de banda da rede enviando apenas o que foi alterado e transferimos a responsabilidade pela atualização do documento do aplicativo para a camada de banco de dados.
Como funcionam as operações de subdocumentos
Seu SDK do Couchbase usa três APIs para trabalhar com o Couchbase Server:
- valor-chave, usando o protocolo binário do memcached
- exibições, usando o protocolo REST do CouchDB
- N1QL, usando o protocolo REST do N1QL.
O SDK abstrai os detalhes, mas, se você já trabalhou com o Couchbase Server, sabe que tipo de interação está tendo.
As operações de subdocumentos ocorrem usando uma extensão do protocolo memcached que lida com suas operações de valor-chave.
Localizar seu subdocumento
Para executar uma operação de subdocumento, você precisa de duas coisas:
- a chave do documento
- o caminho do subdocumento dentro do documento pai.
O que queremos dizer com caminho?
O caminho é o local no documento onde você deseja fazer algo e é a mesma notação usada pelo N1QL.
Digamos que estejamos trabalhando com perfis de clientes para uma loja on-line simples. Aqui está um exemplo de documento de perfil:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "name": "Douglas Reynholm", "email": "douglas@reynholmindustries.com", "addresses": { "billing": { "line1": "123 Any Street", "line2": "Anytown ", "country": "United Kingdom" }, "delivery": { "line1": "123 Any Street", "line2": "Anytown ", "country": "United Kingdom" } }, "purchases": { "complete": [ 339, 976, 442, 666 ], "abandoned": [ 157, 42, 999 ] } |
O caminho para o campo de país no endereço de entrega de nosso cliente seria:
|
1 2 |
addresses.delivery.country |
Da mesma forma, se as compras estiverem listadas do mais recente ao mais antigo, para encontrar o ID da segunda compra mais recente do cliente, usaríamos:
|
1 2 |
purchases.complete[1] |
Portanto, nosso subdocumento é qualquer parte do documento que for encontrada no caminho que fornecemos. Pode ser um objeto enorme ou um único índice em uma matriz.
Uso de operações de subdocumentos
No nível do balde, as coisas são realmente simples. Há apenas dois novos métodos:
- lookupIn(key)
- mutateIn(key).
No Java SDK, ele é implementado usando o padrão builder. Portanto, esses dois métodos bucket criam para nós um objeto, vinculado a um documento específico, no qual podemos fazer o trabalho real de consultar ou alterar nosso subdocumento.
Vamos dar uma olhada em um exemplo em Java, em que estamos encontrando o endereço de entrega do nosso cliente.
|
1 2 |
LookupInBuilder builder = couchbase.bucket().lookupIn('customer123'); |
Em primeiro lugar, estamos criando um objeto construtor que é preparado com o documento do nosso cliente. Em seguida, podemos executar as operações de subdocumento nesse documento do construtor.
|
1 2 3 |
builder = builder.get("addresses.delivery"); DocumentFragment results = builder.doLookup(); |
Se estivermos usando o documento JSON de amostra mencionado anteriormente nesta publicação, resultados será:
|
1 2 3 4 5 6 |
{ "line1": "123 Any Street", "line2": "Anytown ", "country": "United Kingdom" } |
Podemos simplificar essa consulta encadeando tudo:
|
1 2 3 4 |
DocumentFragment results = couchbase.bucket().lookupIn('customer123') .get("addresses.delivery") .doLookup(); |
À medida que criamos consultas e mutações mais complexas, podemos encadear muitas operações. No Java SDK, doLookup indica o fim da consulta e a envia para execução.
Como vimos anteriormente no exemplo de mensagens instantâneas, também podemos modificar documentos usando a API de subdocumentos.
Digamos que queiramos alterar algumas partes do endereço de cobrança de nosso cliente. No Python, poderíamos usar a API de subdocumento para fazer isso da seguinte forma:
|
1 2 3 4 5 |
import couchbase.subdocument as SD cb.mutate_in('customer123', SD.upsert('billing.line1', '123 Main St'), SD.upsert('billing.line2', 'Somewhere')) |
Assim como em Java, primeiro selecionamos o documento por sua chave e, em seguida, realizamos uma série de operações em seu conteúdo.
Próximas etapas
Para obter detalhes sobre como usar a API de subdocumento em seu idioma preferido, consulte a documentação atualizada do SDK.
Você também pode ler a postagem de Mark, que será publicada em breve, com mais detalhes sobre o uso da API de subdocumentos.