Em Blog do Matthew o subdocumento (subdoc) O recurso da API é apresentado com uma breve visão geral: Em resumo, o subdoc permite o acesso eficiente a partes de documentos (submarino-documentos) sem exigir a transferência de todo o documento pela rede.

Ao longo deste blog, usaremos um documento de referência. Esse documento será acessado de várias maneiras usando a API de subdocumentos. Observe que para cada operação de subdocumento, tamanho_doc - tamanho_op bytes de largura de banda estão sendo salvos, onde tamanho_doc é o tamanho do documento, e tamanho_op é o comprimento do caminho e o valor do subdocumento.

O documento abaixo tem 500 bytes. A execução de um simples get() consumiria 500 bytes (mais sobrecarga de protocolo) na resposta do servidor. Se você se importar apenas com o endereço de entrega, poderá emitir um lookup_in('customer123', SD.get('addresses.delivery')) chamada. Você receberia apenas cerca de 120 bytes pela rede, uma economia de mais de 400 bytes, usando um quarto da largura de banda do documento completo equivalente (fulldoc).

Demonstrarei exemplos usando um ramo de desenvolvimento do Python SDK e Visualização para desenvolvedores do Couchbase Server 4.5.
[EDITAR: Uma versão experimental da API de subdocumento já está disponível na versão mais recente do SDK do PythonA versão 2.0.8, e os exemplos abaixo foram atualizados para refletir a API mais recente]

Você pode ler sobre os outros novos recursos do Couchbase 4.5 em Postagem no blog de Don Pinto

Operações de subdocumentos

Uma operação de subdoc é uma ação única para um único caminho em um documento. Isso pode ser expresso como GET('addresses.billing') ou ARRAY_APPEND('purchases.abandoned', 42). Algumas operações são pesquisas (eles simplesmente retornam dados sem modificar o documento), enquanto alguns são mutações (eles modificam o conteúdo do documento).

Muitas das operações de subdoc são equivalentes em escala menor das operações de fulldoc. É útil pensar em um único documento como sendo um armazenamento de valores-chave em miniatura. No SDK do Python, as operações podem ser especificadas por meio de funções especiais na seção couchbase.subdocument que abreviarei no restante deste blog como SD. Isso é feito por

Ao examinar essas operações, observe que o que está sendo transmitido pela rede são apenas os argumentos passados para a própria API subdoc, e não o conteúdo de todo o documento (como aconteceria com o fulldoc). Embora o documento em si possa parecer pequeno, mesmo um simples

Operações de pesquisa

As operações de pesquisa consultam o documento em busca de um determinado caminho e retornam esse caminho. Você tem a opção de realmente recuperação o caminho do documento usando o OBTER operação, ou simplesmente Consultar a existência do caminho usando o EXISTE operação. A última economiza ainda mais largura de banda por não recuperar o conteúdo do caminho se ele não for necessário.

No segundo snippet, também mostro como acessar o último elemento de uma matriz, usando a função especial [-1] componente de caminho.

Também podemos combinar essas duas operações:

Operações de mutação

As operações de mutação modificam um ou mais caminhos no documento. Essas operações podem ser divididas em vários grupos:

  • Operações de dicionário/objeto: Essas operações gravam o valor de uma chave de dicionário JSON.
  • Operações de matriz/lista: Essas operações adicionam operações à matriz/lista JSON.
  • Operações genéricas: Essas operações modificam o próprio valor existente e são independentes do contêiner.

As operações de mutação são tudo ou nadao que significa que todas as operações dentro de mutate_in são bem-sucedidos, ou nenhum deles é.

Operações de dicionário

A mais simples dessas operações é UPSERT. Assim como o upsert em nível de documento completo, ele modificará o valor de um caminho existente ou o criará se ele não existir:

Além de UPSERT, o INSERIR só adicionará o novo valor ao caminho se ele não existir.

Embora a operação acima falhe, observe que qualquer coisa válida como um valor de documento completo também é válida como um valor de subdoc: Desde que possa ser serializado como JSON. O Python SDK serializa o valor acima para [42, true, null].

Os valores do dicionário também podem ser substituídos ou removidos:

Operações de matriz

True array append (ARRAY_APPEND) e prepend (ARRAY_PREPEND) também podem ser executadas usando subdoc. Diferentemente das operações fulldoc append/prepend (que simplesmente concatenam bytes ao valor existente), as operações subdoc append e prepend são compatíveis com JSON:

Você também pode criar um documento somente de matriz e, em seguida, executar matriz_ usando um caminho vazio:

Também existe um suporte limitado para tratar matrizes como conjuntos exclusivos, usando o ARRAY_ADDUNIQUE comando. Isso fará uma verificação para determinar se o valor fornecido existe ou não antes de realmente adicionar o item à matriz:

As operações de matriz também podem ser usadas como base para filas FIFO ou LIFO eficientes. Primeiro, crie a fila:

Adicionar itens ao final

Item de consumo desde o início.

O exemplo acima executa um OBTER seguido de um REMOVER. O REMOVER só é executado quando o aplicativo já tiver o trabalho e só será bem-sucedido se o documento não tiver sido alterado desde então (para garantir que o primeiro item na fila seja o que acabamos de remover).

Operações de combate

As operações de contador permitem a manipulação de um numérico dentro de um documento. Essas operações são logicamente semelhantes às operações de contador em um documento inteiro.

O CONTADOR realiza uma aritmética simples em relação a um valor numérico (o valor é criado se ainda não existir).

CONTADOR também pode diminuir:

Observe que o valor existente para operações de contador deve estar dentro do intervalo de um número inteiro assinado de 64 bits.

Criação de intermediários

Todos os exemplos acima se referem à criação de um único campo novo em um dicionário existente. Entretanto, a criação de uma nova hierarquia resultará em um erro:

Apesar de a operação ser uma UPSERTPor padrão, o subdoc se recusará a criar hierarquias ausentes. O criar_pais No entanto, a opção permite que ele seja bem-sucedido: adicione o nível de protocolo em que a opção é chamada F_MKDIRP, como o -p da opção mkdir em plataformas do tipo Unix.

Subdocumento e CAS

O subdoc elimina principalmente a necessidade de rastreamento CAS. As operações de subdoc são atômicas e, portanto, se dois threads diferentes acessarem dois subdocumentos diferentes, não haverá conflito. Por exemplo, os dois blocos a seguir podem ser executados simultaneamente sem nenhum risco de conflito:

Mesmo ao modificar o mesmo parte do documento, as operações não necessariamente entrarão em conflito, por exemplo, duas operações simultâneas ARRAY_PREPEND para o mesmo array serão bem-sucedidos, nunca substituindo o outro.

Isso não significa que o CAS não seja mais necessário - às vezes é importante garantir que o documento completo não mudou de estado desde a última operação: isso é especialmente importante no caso de REMOVER para garantir que o elemento que está sendo removido não tenha sido substituído por outra coisa.

Perguntas frequentes sobre operações de subdocumentos no Couchbase

No decorrer do desenvolvimento do subdoc, fizeram-me várias perguntas sobre o que ele faz, e eu responderei em seguida:

Qual é a diferença entre Subdoc e N1QL?

O N1QL é uma linguagem de consulta rica e expressiva que permite que você pesquise e possivelmente altere vários documentos de uma só vez. Subdoc é uma API/implementação de alto desempenho projetada para pesquisar em um documento único.

Subdoc é um alto desempenho conjunto de APIs simples e discretas para acessar dados em um único documento, com o objetivo de reduzir largura de banda da rede e aumentando a taxa de transferência geral. Ele é implementado como parte do serviço KV e, portanto, é bastante consistente com ele.

N1QL é um linguagem de consulta avançada capaz de pesquisar vários documentos no Couchbase que atendam a determinados critérios. Ele opera externo o serviço de KV, fazendo solicitações otimizadas de KV e índice para satisfazer as consultas recebidas. A consistência com o serviço de KV é configurável por consulta (por exemplo, o USAR CHAVES e a cláusula scan_consistency opção).

Quando devo usar o N1QL e quando devo usar o subdoc?

O N1QL responde a perguntas como Encontre todos os documentos em que X=42 e Y=77 Enquanto o subdoc responde a perguntas como Obter X e Y do documento Z. Mais especificamente, o subdoc deve ser usado quando todos os IDs de documentos são conhecidos (em outras palavras, se uma consulta N1QL contiver USAR CHAVES pode ser um candidato a subdoc).

No entanto, os dois não são mutuamente exclusivos, e é possível usar tanto o N1QL quanto o subdoc em um aplicativo.

São mutate_in e lookup_in atômica?

Sim, elas são atômicas. Ambas as operações têm a garantia de ter todos os seus subcomandos (por exemplo CONTADOR, OBTER, EXISTE, ADD_UNIQUE) operam na mesma versão do documento.

Como faço para acessar vários documentos com subdoc?

Não há nenhuma boa fé multi operação para subdoc, pois subdoc opera dentro do escopo de um único documento. Como os documentos são fragmentados no cluster (isso é comum ao Couchbase e a todos os outros armazenamentos NoSQL), as operações múltiplas não poderiam garantir o mesmo nível de transações e atomicidade entre os documentos.

Não gosto da convenção de nomes para matrizes. Por que você não usou anexar, adicionaretc.?

Há muitas linguagens no mercado e parece que todas elas têm uma ideia diferente de como chamar as funções de acesso ao array:

  • Genérico: adicionar ao final, adicionar à frente
  • C++: push_back(), push_front()
  • Python: anexar(), inserir(0), estender
  • Perl, Ruby, Javascript, PHP: push(), unshift()
  • Java, C#: add()

O termo anexar já é usado no Couchbase para se referir à concatenação de bytes do documento completo, por isso considerei inconsistente usar esse termo de uma maneira ainda diferente no subdoc.

Por que a CONTADOR requerem números inteiros assinados de 64 bits?

Isso é resultado do fato de o código do subdoc ser implementado em C++. Implementações futuras poderão permitir uma faixa mais ampla de valores numéricos existentes (por exemplo, valores grandes, valores não integrais etc.).

Como faço para executar um pop? por que não há POP operação?

POP refere-se ao ato de remover um item (por exemplo, de uma matriz) e devolvê-lo, em uma única operação.

POP pode de fato ser implementado no futuro, mas usá-lo é inerentemente perigoso:

Como a operação está sendo feita pela rede, é possível que o servidor tenha executado a remoção do item, mas que a conexão de rede tenha sido encerrada antes que o cliente receba o valor anterior. Como o valor não está mais no documento, ele é perdido permanentemente.

Posso usar o CAS com operações de subdocumentos?

Sim, com relação ao uso do CAS, as operações de subdoc são operações normais da API KV, semelhantes a upsert, obteretc.

Posso usar requisitos de durabilidade com operações de subdoc?

Sim, com relação aos requisitos de durabilidade, mutate_in é visto como upsert, inserir e substituir.

Autor

Postado por Mark Nunberg, engenheiro de software, Couchbase

Mark Nunberg é um engenheiro de software que trabalha na Couchbase. Ele mantém a biblioteca do cliente em C (libcouchbase), bem como o cliente em Python. Ele também desenvolveu o cliente Perl (para uso em sua empresa anterior), o que o levou inicialmente a trabalhar no Couchbase. Antes de ingressar no Couchbase, ele trabalhou em sistemas de roteamento distribuídos e de alto desempenho em uma empresa de análise de comércio eletrônico. Mark estudou Linguística na Universidade Hebraica de Jerusalém.

Deixar uma resposta