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.obter('chatlog') # Obter o documento completo rv.doc.mensagens += ['nvm lol'] # Modificar o documento localmente cb.substituir(rv.chave, rv.doc, cas=rv.cas) # Carregar todo o documento novamente |
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 |
importação couchbase.subdocumento como SD cb.mutate_in('chatlog', SD.anexar('mensagens', '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" (nome): "Douglas Reynholm", "email": "douglas@reynholmindustries.com", "endereços": { "faturamento": { "line1": "123 Any Street" (123 Qualquer Rua), "line2": "Qualquer cidade", "país": "Reino Unido" }, "entrega": { "line1": "123 Any Street" (123 Qualquer Rua), "line2": "Qualquer cidade", "país": "Reino Unido" } }, "compras": { "completo": [ 339, 976, 442, 666 ], "abandonado": [ 157, 42, 999 ] } |
O caminho para o campo de país no endereço de entrega de nosso cliente seria:
1 2 |
endereços.entrega.país |
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 |
compras.completo[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 construtor = couchbase.balde().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 |
construtor = construtor.obter("addresses.delivery"); Fragmento de documento resultados = construtor.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" (123 Qualquer Rua), "line2": "Qualquer cidade", "país": "Reino Unido" } |
Podemos simplificar essa consulta encadeando tudo:
1 2 3 4 |
Fragmento de documento resultados = couchbase.balde().lookupIn('customer123') .obter("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 |
importação couchbase.subdocumento como SD cb.mutate_in('customer123', SD.upsert('billing.line1', '123 Main St'), SD.upsert('billing.line2', "Em algum lugar)) |
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.