Muitas perguntas aparecem no fórum do Couchbase e no Stack Overflow com relação à leitura e gravação de apenas partes de um documento em vez do documento completo. Posso ver onde isso pode ser uma preocupação. Por exemplo, e se você tiver documentos com megabytes de tamanho? A transferência desses documentos grandes entre a camada do aplicativo e o Couchbase Server pode se tornar bastante lenta.
É aqui que a API de subdocumentos do Couchbase, parte do Servidor Couchbase 4.5, entra em ação. Em vez de obter um documento completo e potencialmente grande com base em uma chave, você pode obter apenas as partes do documento de que precisa. O mesmo pode ser dito sobre a gravação de alterações de volta no Couchbase. Por exemplo, e se você tiver um documento com dados de perfil de usuário e só precisar alterar o endereço? Não faria mais sentido escrever apenas essa alteração?
Vamos dar uma olhada no uso da API de subdocumentos em um aplicativo Node.js usando o SDK do Node.js para o Couchbase. Antes de começarmos a fazer isso, vamos criar uma história. Digamos que temos um perfil de usuário com dados de mídia social. Vamos basear nossas manipulações apenas nos dados de mídia social, não no restante do documento. Assim, por exemplo:
|
1 2 3 4 5 6 7 8 9 |
{ firstName: "Nic", lastName: "Raboy", redes sociais: { twitter: "nraboy" } } |
O documento JSON acima será o documento base com o qual trabalharemos.
Para facilitar a compreensão, vamos criar um novo projeto do Node.js para trabalhar. Para maior clareza, vamos nos basear nesse novo projeto. Supondo que o Node.js esteja instalado e que você tenha o Couchbase Server 4.5+ em execução em algum lugar, execute o seguinte no prompt de comando ou no terminal:
|
1 2 3 4 |
npm inicial -y npm instalar couchbase --salvar |
Provavelmente, você deve criar um novo diretório antes de executar os comandos acima, mas eles basicamente criarão um novo projeto Node.js e instalarão o SDK do Couchbase Node.js. Crie um projeto app.js no mesmo diretório que abrigará nossa lógica.
Daqui para frente, passaremos nosso tempo no app.js arquivo. Abra-o e vamos adicionar o código básico de inicialização para conectar-se ao Couchbase.
|
1 2 3 4 5 6 |
var Couchbase = exigir("couchbase"); var agrupamento = novo Couchbase.Aglomerado("couchbase://localhost"); var balde = agrupamento.openBucket("default"); |
No exemplo acima, estamos nos conectando a uma instância do Couchbase em execução local e abrindo o arquivo padrão balde. Sinta-se à vontade para alterar isso conforme apropriado. Agora, vamos prosseguir com a criação das quatro funções JavaScript a seguir:
|
1 2 3 4 5 6 |
var createDocument = função(documentId, documento) { } var getSubDocument = função(documentId) { } var upsertSubDocument = função(documentId) { } var getDocument = função(documentId, isFinished) { } |
Estamos criando quatro funções para evitar uma cadeia gigante aninhada de retornos de chamada de funções assíncronas. Como nosso projeto será concebido mais como um script, uma cadeia pode ser um pouco difícil de acompanhar.
Vamos seguir a linha com cada uma dessas funções em ordem. Começando com a função createDocument ela terá a seguinte aparência:
|
1 2 3 4 5 6 7 8 9 10 |
var createDocument = função(documentId, documento) { balde.upsert(documentId, documento, (erro, resultado) => { se(erro) { retorno console.registro("ERRO: ", erro); } getSubDocument(documentId); }); } |
A função acima pressupõe que estamos passando uma chave de documento e um documento JSON. Não se preocupe, veremos isso no final. No entanto, o que está acontecendo é que estamos fazendo uma upsert para criar um novo documento completo. Basicamente, estamos usando essa função como nossa função de inicialização para este exemplo. Quando o documento de perfil completo for criado, ele chamará a próxima função quando for bem-sucedido. Essa próxima função é a getSubDocument e ele se parece com o seguinte:
|
1 2 3 4 5 6 7 8 9 10 |
var getSubDocument = função(documentId) { balde.lookupIn(documentId).obter("socialNetworking").executar((erro, resultado) => { se(erro) { lançar erro; } upsertSubDocument(documentId); }); } |
A função acima pegará a chave inicial do documento que definimos e declarará que faremos uma pesquisa em vez de obter um documento. Ao fazer nossa pesquisa, estamos procurando o redes sociais e, em seguida, executamos essa pesquisa. Podemos obter mais de uma propriedade se quisermos, pois o resultado da execução retornará uma matriz de propriedades. Por exemplo, a matriz do conteúdo do resultado acima teria a seguinte aparência:
|
1 2 3 |
[ { id: 0, valor: { twitter: 'garoto' }, caminho: 'redes sociais' } ] |
Após o getSubDocument for concluída com êxito, ela chamará a função upsertSubDocument que nos permite alterar uma parte do documento sem primeiro obter o documento completo, ou mesmo parte dele.
|
1 2 3 4 5 6 7 8 9 10 |
var upsertSubDocument = função(documentId) { balde.mutateIn(documentId, 0, 0).upsert("socialNetworking.website", "thepolyglotdeveloper.com", verdadeiro).executar((erro, resultado) => { se(erro) { lançar erro; } getDocument(documentId); }); } |
Vamos ser claros aqui. Quando estivermos usando o mutateIn acima, não estamos obtendo o documento primeiro. Ele funciona mais ou menos como a pesquisa que fizemos anteriormente. Estamos informando ao Couchbase qual documento planejamos alterar com base na chave e, em seguida, estamos inserindo uma propriedade específica. No exemplo acima, estamos tentando criar uma nova propriedade chamada site. É uma propriedade aninhada, portanto, estamos passando o caminho completo junto com o valor dessa propriedade. Em seguida, podemos executar a solicitação.
Por fim, queremos ver o documento completo com o qual ficamos. Supondo que a mutação tenha sido bem-sucedida, o getDocument será chamada. Ela se parecerá com o seguinte:
|
1 2 3 4 5 6 7 8 9 10 |
var getDocument = função(documentId) { balde.obter(documentId, (erro, resultado) => { se(erro) { lançar erro; } console.registro(resultado); }); } |
Na função acima, estamos apenas fazendo um obter por chave de documento. Para finalizar, é provavelmente uma boa ideia compartilhar o trecho de código que chamou nossa primeira função. Ele pode ser visto da seguinte forma:
|
1 2 3 4 5 6 7 8 9 |
createDocument("nraboy", { firstName: "Nic", lastName: "Raboy", redes sociais: { twitter: "nraboy" } }); |
Conclusão
A API de subdocumentos do Couchbase é incrivelmente benéfica ao trabalhar com documentos maiores. Você pode não apenas obter partes de um documento para reduzir o tamanho da transferência, mas também pode gravar partes. Compartilhei apenas parte do que é possível fazer com a API para Node.js. Para obter outro exemplo, visite este no GitHub. Outros comandos podem ser vistos no SDK do Node.js documentação.