Hoje, surgiu uma pergunta de um desenvolvedor que queria migrar de outra coisa para o Couchbase. Essa "outra coisa" tinha um documento JSON com alguns metadados. O Couchbase separa os dados dos metadados por alguns bons motivos, portanto, precisaríamos remover esse campo "_id". Felizmente, é bastante fácil escrever um método de extensão para fazer isso com o SDK do .NET ou, se você estiver usando POCOs (Plan Ole' Csharp Objects), use um ContractResolver personalizado.
O cenário
Suponha que você tenha um documento parecido com este, talvez armazenado em disco:
O que você deseja fazer é remover sem problemas o id do próprio documento e torná-lo a chave do documento que será inserido no Couchbase. Quando isso for feito, haverá dois documentos armazenados no Couchbase: o próprio documento e os metadados do documento.
Metadados do documento? Conteúdo? Qual é a diferença?
Metadados são dados sobre o próprio documento, mas não sobre o conteúdo do documento. Ele contém os seguintes valores:
- TTL - tempo de expiração do documento
- CAS - comparar e trocar valores para garantir a simultaneidade otimista em uma chave
- Bandeiras - Metadados específicos do SDK para transcodificação
- Número de sequência - um valor usado internamente no Couchbase para a resolução de conflitos de chaves que são atualizadas em clusters diferentes - algo como replicação entre centros de dados (XDCR)
- Chave - o identificador exclusivo do próprio documento
Todas essas informações são úteis fora do conteúdo em si, tão importantes que são separadas e persistem na memória. O tamanho dos metadados varia entre as versões do Couchbase; a partir da versão 2.1.0, ele é de 54k, o que é bastante pequeno. Agora, o conteúdo do documento é o JSON real ou os dados binários em si.
Uso de resolvedores de contrato personalizados com métodos de extensão
Há duas coisas que precisamos fazer: obter o valor-chave para o "_id" do documento e, em segundo lugar, garantir que, durante a serialização, o valor "_id" não seja persistido com o conteúdo. O primeiro requer que analisemos a cadeia de caracteres JSON e extraiamos o "_Id" e, em seguida, o atribuímos ao novo documento que será inserido no Couchbase. Isso pode ser feito de duas maneiras: usando um ContractResolver personalizado ou manipulando o JSON como um JObject em si. Acontece que, para oferecer suporte a POCOs e à palavra-chave dinâmica, você precisa fazer as duas coisas.
O IgnoreFieldContractResolver
O SDK do Couchbase .NET, por padrão, usa o Estrutura JSON da NewtonSoft para .NET. Ao configurar o cliente, há um gancho para atribuir um resolvedor de contrato personalizado. Um contrato resolve os campos de seu JSON para seu modelo de objeto. Um resolvedor personalizado permite que você faça coisas como ignorar ou modificar campos no seu JSON... ele funciona como um filtro.
Aqui está a listagem de um resolvedor personalizado que ignora qualquer nome de campo que você passar para o construtor:
Não há muita coisa acontecendo aqui, basicamente estamos derivando do DefaultContractResolver e substituindo o método CreateProperties. Nesse caso, estamos omitindo a serialização da JsonProperty que é o nome do campo FieldToIgnore. Se você agora definir a ClientConfiguration para usá-lo, assim:
Então, todos os documentos JSON que forem serializados terão seu FieldToIgnore removido; em nosso caso, usamos o campo "_id", pois não queremos que ele seja mantido (já que ele se tornará a chave de metadados).
Extraindo o Id e inserindo o JSON com um método de extensão
Agora que temos um resolvedor de contratos que removerá o campo "_id" de qualquer JSON que inserirmos usando o cliente, podemos extrair o ID do documento (o valor de "_id") e usá-lo como chave para a inserção.
Observe que há dois casos (principais) para armazenar JSON (de uma perspectiva de SDK) no Couchbase. Você pode armazenar um POCO que representa o documento JSON ou pode inserir o documento JSON como um tipo dinâmico. Cada um deles exige uma consideração especial, mas é muito fácil escrever um método de extensão que abstraia isso:
A consideração "especial" aqui para tipos dinâmicos é que você não pode confiar na reflexão sobre T, pois T será um objeto. Você precisa criar um JObject primeiro e depois usá-lo para obter o valor de "_id".
Quando você tiver esse método de extensão implementado, poderá escrever um código simples como este para extrair um arquivo JSON do disco, extrair a chave e inseri-la no Couchbase:
Observe que, para o POCO, você direciona o campo "Id" e, para o dinâmico, direciona o "_id". Isso ocorre simplesmente porque, no dinâmico, extraímos o valor diretamente do JObject e, portanto, ele refletirá o invólucro e as convenções do JSON original.
Agora, se você observar o documento JSON no Couchbase Managment Console, verá que o campo "_id" foi removido do documento e usado como chave:
Obtendo a fonte:
Se você quiser brincar com a fonte que usei para esta postagem, ela'está em laboratórios couchbase no Github. A intenção do projeto (couchbase-net-contrib) é fornecer extensões e plug-ins que são comumente usados ao trabalhar com o SDK do Couchbase, mas provavelmente não serão incluídos no SDK real. A intenção é que ele seja orientado pela comunidade, portanto, sinta-se à vontade para enviar solicitações de pull com quaisquer contribuições que você ache que seriam úteis para os outros!