Esta postagem do blog é baseada em um post anterior do blog de Jeff Morris que cobriu a API de subdocumentos enquanto ela ainda estava na versão prévia para desenvolvedores. Houve algumas alterações na API desde esse lançamento.

Com Servidor Couchbase 4.5 e o .NET SDK 2.3.xAgora você pode usar o Subdocumento em seu aplicativo .NET.

Nas versões anteriores do Couchbase, todas as mutações de documentos eram atômicas e envolviam o documento inteiro. Se você quiser alterar apenas um único campo e depois fazer uma atualização, todo o documento no servidor Couchbase será copiado pela nova revisão. O problema é que, se o documento for grande ou a rede for lenta (ou ambos), muitos recursos serão desperdiçados com o envio de dados que não foram modificados. Uma solução melhor e de melhor desempenho seria enviar apenas a parte do documento ou o valor que sofreu mutação. Essencialmente, é isso que você obtém com a API de subdocumento; quando você atualiza um elemento ou exclui um elemento de um documento, somente o caminho do fragmento a ser alterado é enviado pela rede e somente essa parte do documento é modificada.

Subdocument

Há várias operações diferentes que são suportadas pela API, desde mutações em elementos individuais aninhados (também conhecidos como subdocumentos) para modificações em matrizes e dicionários. As operações de contador também são suportadas, assim como as operações de recuperação de fragmentos JSON incorporados.

A API é exposta por meio de um fluente que permite anexar várias operações e executá-las atomicamente no documento. Há dois "construtores" diferentes: um construtor para operações de mutação e um construtor para leituras ou "pesquisas" (que também pode verificar se um elemento existe em um determinado caminho).

Pré-requisito: Couchbase Server 4.5

Para seguir os exemplos abaixo, você precisará fazer o download e instalar Servidor Couchbase 4.5. Se você nunca instalou o Couchbase Server antes, assista ao meu vídeo sobre Como instalar o Couchbase Server no Windows. É muito fácil, independentemente do sistema operacional que estiver usando.

Visão geral da API do subdocumento

Os exemplos a seguir usarão um documento com um ID de "puppy" e começarão com a seguinte aparência:

Todos os Os exemplos estão disponíveis no Github para que você possa clonar o projeto e brincar com a API.

MutateInBuilder e LookupInBuilder

A API de subdocumentos oferece dois novos tipos que utilizam um padrão de construtor por meio de uma interface fluente para encadear várias operações em um documento. Ambos os objetos são criados chamando Mutação ou Pesquisa em um CouchbaseBucket e passando a chave do documento com o qual você está trabalhando:

Depois de ter o objeto construtor, você pode encadear várias operações para executar no documento, por exemplo:

Em seguida, você pode enviar todas as operações para o servidor em um único lote:

Você pode verificar o resultado de uma operação usando OpStatus e um caminho. Neste exemplo, estou usando o caminho "tipo":

Estes são alguns dos métodos e campos que você encontrará no IDoc DocumentFragment interface.

Nome

Descrição

Conteúdo(...)

Obtém o conteúdo de um determinado caminho ou índice.

Existe(...)

Retorna true se houver um resultado para um determinado caminho ou índice.

Count()

O número de operações atuais mantidas pelo construtor.

OpStatus(...)

O Status da resposta de uma operação em um determinado índice ou caminho.

Status

O Status da resposta para toda a operação múltipla.

Sucesso

Verdadeiro se toda a operação múltipla for bem-sucedida.

Além dessas propriedades ou métodos, há todas as outras propriedades herdadas de Resultado da operação (que é a resposta padrão de uma operação de chave/valor): Upsert, Remove, Replace e assim por diante.

Tratamento de erros

Ao enviar vários mutaçõesSe um deles falhar, toda a solicitação de várias operações falhará. Isso permite uma semântica transacional do tipo "tudo ou nada" ao realizar mutações em um único documento.

Ao enviar vários pesquisasSe o servidor tentar retornar tantos itens quantos forem solicitados, algumas operações poderão ser bem-sucedidas e outras poderão falhar.

Se a(s) operação(ões) falhar(em), oStatus conterá uma resposta de erro de nível superior, como SubDocMultiPathFailure. Essa é uma indicação de que você deve se aprofundar nos resultados da operação para obter o erro específico. Você pode fazer isso por meio de iteração: chamando a função Status da operação e passando o índice ou o caminho:

Nesse caso, como o caminho "somepaththatdoesntexist" não existia no documento, o erro específico retornado foi SubDocPathNotFound. Há muitas combinações diferentes de erros, dependendo do tipo de construtor e da condição do erro.

Exemplos de LookupInBuilder

O LookUpInBuilder suporta duas operações: buscar um valor por caminho e verificar a existência de um valor em um determinado caminho.

Obter:

Vamos procurar o proprietário fragmento. Se eu passar "owner" como parâmetro de caminho para esse método...

...a saída para o console seria:

Existir:

Também podemos verificar se um caminho existe. Se eu passar "owner" como o caminho para esse método...

...o resultado é verdadeiroporque o caminho proprietário existe de fato no documento.

MutateInBuilder

O MutateInBuilder oferece vários métodos de suporte a mutações em valores escalares, dicionários e matrizes, além de suporte a operações de contador atômico.

Inserir:

Insert adiciona um valor a um dicionário e, opcionalmente, permite que o elemento que o contém (o próprio dicionário) seja adicionado.

Se eu chamasse o método acima dessa forma:

Então, o dicionário de atributos do documento terá a seguinte aparência:

Observe que o Inserir tem um parâmetro booleano opcional chamado createParents. É falso por padrão. Se for verdadeiro, a API do subdocumento criará o caminho necessário para que o campo exista. Se for falso, a API do subdocumento só criará o campo se os pais do campo já existirem. No exemplo acima, o campo atributos já existia.

No próximo exemplo, usarei um caminho com um campo pai (um novo atributo) que ainda não exista.

Isso criará o novo atributo chamado um novo atributo no documento e adicione uma única chave chamada withakey com um valor de algum valor.

Agora, se passarmos falso para createParents e o atributo pai não existisse, a mutação múltipla falharia com um status de resposta de nível superior de SubDocMultiPathFailure e o erro específico seria SubDocPathNotFound.

Upsert

Upsert adiciona ou substitui uma entrada existente no dicionário. O uso é exatamente o mesmo que Inserir com exceção do nome do método que é Upsert.

Remover

Remover removerá um elemento em um determinado caminho.

Quando chamo esse método:

Veja como o documento ficará depois:

Substituir

Replace trocará o valor do elemento em um determinado caminho, falhando se o caminho não existir:

Depois que eu chamar esse método:

O documento agora terá um valor diferente para "proprietário":

ArrayAppend

O ArrayAppend adiciona um valor ao final de uma matriz, adicionando opcionalmente o elemento pai (o próprio elemento da matriz) se ele não existir.

Depois desse método com o caminho "toys"...

...o brinquedos no documento terá o valor "slipper" no último ordinal:

ArrayPrepender

O ArrayPrepend funciona da mesma forma que o ArrayAppend, exceto pelo fato de que ele adiciona um valor à variável frente de uma matriz.

Chamando esse método com o caminho "toys"...

O brinquedos agora tem o valor "slipper" em sua matriz primeiro ordinal:

ArrayInsert

O ArrayPrepend coloca um valor no início, o ArrayAppend o coloca no final. Para completar, você pode usar o ArrayInsert para colocar um valor em algum ponto intermediário (em um determinado índice).

E, em seguida, chamar esse método com "toys[2]"...

O brinquedos A matriz agora tem o valor "slipper" em seu terceiro ordinal (índice 2):

ArrayAddUnique

O ArrayAddUnique insere um valor em uma matriz, mas falhará se esse valor já existir (ou seja, o valor deve ser exclusivo dentro da matriz).

Quando eu chamo isso de "sapato"...

...uma vez que o valor "shoe" já existe no documento original brinquedos isso falhará com o status SubDocPathExists.

Observe que esse método só permite a inserção de primitivos JSON: cadeias de caracteres, números e valores especiais para verdadeiro, falso ou nulo. Não há como comparar a exclusividade sem descer em cada objeto JSON e comparar os elementos item por item.

Balcão

Adiciona o delta especificado (alteração) a um valor existente, criando o elemento se ele não existir. O valor e o delta serão padronizados como 0. Se o delta for negativo, o valor do elemento será diminuído pelo delta fornecido.

Criarei um método que usa Balcão:

Em seguida, chamarei o método duas vezes usando um 1 positivo e um 1 negativo como "deltas":

Após a primeira chamada, como o elemento não existe, ele será criado e, em seguida, definido como um (1). O documento agora terá a seguinte aparência:

A segunda chamada passa um número negativo (-1), portanto, o contador para gostos será decrementado para zero (0). O documento JSON agora terá a seguinte aparência:

Conclusão

Desde a publicação no blog da visualização do desenvolvedor, o SDK do Couchbase .NET foi atualizado para a versão 2.3.2 (até o momento desta publicação no blog). Você pode conferir o trabalho que foi feito na seção Notas de versão da versão 2.3.2.

Notas finais

A API de subdocumentos permite que você seja mais granular em suas interações com os documentos. Você pode modificar e recuperar apenas as partes de que precisa.

Deixe um comentário abaixo, fale comigo no Twitterou envie um e-mail para mim (matthew.groves AT couchbase DOT com) se tiver alguma dúvida ou comentário.

Autor

Postado por Matthew Groves

Matthew D. Groves é um cara que adora programar. Não importa se é C#, jQuery ou PHP: ele enviará solicitações de pull para qualquer coisa. Ele tem programado profissionalmente desde que escreveu um aplicativo de ponto de venda QuickBASIC para a pizzaria de seus pais nos anos 90. Atualmente, ele trabalha como gerente sênior de marketing de produtos da Couchbase. Seu tempo livre é passado com a família, assistindo aos Reds e participando da comunidade de desenvolvedores. Ele é autor de AOP in .NET, Pro Microservices in .NET, autor da Pluralsight e Microsoft MVP.

Deixar uma resposta