Prólogo
Este artigo o orienta em uma migração única do MongoDB para o Couchbase. Você aprenderá a exportar da estrutura de dados do MongoDB, importar para o Couchbase e fazer algumas transformações básicas nesses documentos.
Todo o código deste blog está disponível no seguinte repositório Git: mongodb-to-couchbase
Pré-requisitos
Este artigo usa o conjunto de dados de amostra mflix que foi carregado em um cluster do MongoDB. Estou usando o MongoDB Atlas, mas as informações deste artigo também se aplicam a instalações do MongoDB que não sejam do Atlas. Se você precisar carregar o conjunto de dados de amostra para o MongoDB, consulte o artigo instruções aqui.
MongoDB Compass é usado para exportar o conjunto de dados e este artigo pressupõe que ele já esteja configurado para se conectar ao cluster do MongoDB onde reside o conjunto de dados de amostra mflix.
Você também precisará de um cluster do Couchbase Server Enterprise Edition (EE) 6.5 com os serviços Data, Index, Query e Eventing ativados (OBSERVAÇÃO: Index e Query serão usados em um artigo futuro). Estou usando uma instalação local de nó único do Couchbase Server EE, mas as informações neste artigo se aplicam a qualquer cluster do Couchbase Server EE.
Se você não tiver um cluster existente do Couchbase Server EE, os links a seguir o ajudarão a começar a trabalhar rapidamente:
- Faça o download do Couchbase Sever EE 6.5
- Instalar o Couchbase Server EE
- Provisione um cluster de nó único (OBSERVAÇÃO: use os valores padrão para a configuração do cluster).
JSON, BSON e JSON estendido
O MongoDB e o Couchbase são bancos de dados de documentos e ambos armazenam documentos JSON. No entanto, o MongoDB representa documentos JSON em um formato codificado em binário chamado BSON. O JSON só pode representar um subconjunto dos tipos suportados pelo BSON. Para preservar as informações de tipo, o MongoDB usa o Extended JSON, que inclui extensões para o formato JSON. Consulte a seção Especificação JSON estendida do MongoDB para obter detalhes completos sobre os diferentes tipos e convenções do Extended JSON.
Aqui estão alguns exemplos de como o MongoDB representa diferentes tipos de informações:
- ObjectId: “_id”:{“$oid”:”573a1390f29313caabcd4135″}
- Inteiro: "runtime":{"$numberInt": "1″}
- Data: “released”:{“$date”:{“$numberLong”:”-2418768000000″}}
- Duplo: "rating":{"$numberDouble": "6.2″}
Embora o Couchbase possa armazenar essas informações, é mais fácil trabalhar com documentos que não usam o formato JSON estendido. Usando os exemplos acima, os valores teriam a seguinte aparência:
- ObjectId: “_id”:”573a1390f29313caabcd4135″
- Inteiro: "runtime":1
- Data: “released”:-2418768000000
- Duplo: "rating":6.2
Exportar dados do MongoDB
Use o MongoDB Compass para exportar o filmes e comentários coleções do sample_mflix banco de dados. No Compass, expanda a seção sample_mflix item do banco de dados e, em seguida, selecione comentários.
Escolha o Coleção -> Coleção de exportação item de menu. Selecione Exportar coleção completa e clique em SELECIONAR CAMPOS.
Selecione todos os campos e clique em SELECIONAR SAÍDA.
Selecione JSON tipo de arquivo de exportação, especifique o arquivo de saída e clique em EXPORTAÇÃO.
Faça o mesmo com o filmes coleção.
Importar dados para o Couchbase
Em seguida, importe os dados da coleção do MongoDB para o Couchbase. Conforme mencionado acima, os dados exportados estão no formato JSON estendido, portanto o Couchbase Serviço de eventos é usado para fazer algumas pequenas transformações nos dados em tempo real à medida que os documentos são importados para o Couchbase.
Em um nível elevado, o fluxo é o seguinte:
- Use o Utilitário cbimport para importar os documentos JSON para o de entrada balde.
- Como os documentos são gravados no de entrada balde, uma função Eventing transformará os documentos.
- Se a transformação for bem-sucedida, o documento transformado será gravado no arquivo sample_mflix balde.
- Se houver algum erro, o documento original é gravado no erro balde. Um atributo de erro no documento conterá a mensagem de erro.
Criar baldes
Crie os três buckets mencionados acima. Consulte a seção documentação sobre a criação de um bucket para obter detalhes completos sobre as diferentes configurações e considerações sobre a definição dos valores.
O de entrada O bucket armazenará temporariamente os documentos à medida que eles forem importados para o Couchbase. Esse é um balde efêmero já que não precisamos de nenhum armazenamento persistente para esses documentos. Uma função Eventing os transformará e os gravará no sample_mflix ou no bucket de erros.
Como os documentos não precisam permanecer no bucket depois de serem transformados, o bucket é configurado com um Tempo de vida (TTL) de 900 segundos (15 minutos). Os documentos são excluídos automaticamente pelo Couchbase quando o TTL expirações.
Para criar o de entrada clique em Baldes e depois ADICIONAR BALDE.
Configurar o de entrada como segue e clique em Adicionar balde.
- Nome: entrada
- Cota de memória: 256 MB (OBSERVAÇÃO: os compartimentos efêmeros não persistem no disco, portanto, é necessário garantir que haja memória suficiente alocada ao compartimento para acomodar todo o conjunto de dados que está sendo importado. O tamanho total das coleções de comentários e filmes usadas neste exemplo é de cerca de 50 MB, portanto, 256 MB é mais do que suficiente para acomodar esse conjunto de dados).
- Tipo de caçamba: Efêmero
- Configurações avançadas do Bucket -> Tempo máximo de vida do balde(OBSERVAÇÃO: os documentos são transformados em tempo real à medida que são gravados no Couchbase, portanto, esse valor pode ser definido como relativamente baixo. No caso, são usados 15 minutos (900 segundos). Se o valor for definido como muito baixo, o documento poderá expirar antes de ser processado).
O sample_mflix é usado para armazenar o documento transformado. Esse é um Balde do Couchbase já que precisamos de armazenamento persistente para esses documentos. Configure-o da seguinte forma:
- Nome: sample_mflix
- Cota de memória256 MB (OBSERVAÇÃO: os buckets do Couchbase persistem todos os documentos no disco, portanto, a cota de memória determinará quantos documentos podem ser armazenados no camada de cache integrada a qualquer momento. O tamanho total das coleções de comentários e filmes usadas neste exemplo é de cerca de 50 MB, portanto, 256 MB é mais do que suficiente para acomodar esse conjunto de dados).
- Tipo de caçamba: Couchbase
O erro é usado para armazenar todos os documentos que não puderam ser transformados. Configure-o da seguinte forma:
- Nome: erro
- Cota de memória: 256 MB
- Tipo de caçamba: Couchbase
Transformação de dados com eventos
Eventos é usado para transformar os dados em tempo real à medida que eles são importados para o Couchbase. Há algumas coisas a serem configuradas para usar esse recurso.
Primeiro, crie um metadados balde que é usado pelo Eventing para armazenar dados do sistema. Configure-o da seguinte forma:
- Nome: metadados
- Cota de memória: 256 MB
- Tipo de caçamba: Couchbase
O Baldes agora lista os 4 compartimentos que você criou: error, incoming, metadata e sample_mflix:
Clique em Eventos e, em seguida, clique em ADICIONAR FUNÇÃO para configurar a função que é usada para transformar os dados em tempo real à medida que são importados para o Couchbase.
Configure a função da seguinte forma:
- Balde de origem: incoming (Esse bucket armazena temporariamente os documentos à medida que eles são importados para o Couchbase)
- Balde de metadadosMetadados: (Esse compartimento é usado para armazenar dados do sistema)
- Nome da função: transformação
- Descrição: Transformar a exportação do MongoDB
- Vinculações (Clique no botão + para adicionar um segundo vínculo)
- tipo de ligação: alias do balde
- nome do aliastarget (alias usado na função para se referir ao bucket)
- balde: sample_mflix (nome do bucket no cluster)
- acesso: leitura e gravação
-
- tipo de ligação: alias do balde
- nome do aliasErro (alias usado na função para se referir ao bucket)
- balde: erro (nome do bucket no cluster)
- acesso: leitura e gravação
Clique em Próximo: Adicionar código para adicionar o código JavaScript para o transformar função.
Na tela da função de transformação, substitua o código padrão pelo código abaixo.
A função inclui instruções log() para registrar o documento original, o documento transformado e quaisquer erros. Fique à vontade para alterá-las conforme necessário. O arquivo de registro de entradas do Eventing é eventing.log e pode ser encontrado no registro do aplicativo @eventing. Veja este link para obter mais informações sobre o nome do arquivo de registro e como visualizá-lo.
Você pode facilmente ampliar a capacidade dessa função para realizar outras transformações adicionando o código necessário na função transformValues(). Se precisar fazer alguma alteração na função, você precisará pausar ou cancelar a implantação, editar o JavaScript e, em seguida, retomar ou implantar novamente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
função Sobre a atualização(doc, meta) { registro("documento original: ", doc); tentar { // transformar documento var novoDoc = TransformValues(nulo, "", doc); // adicionar um atributo de tipo com base no ID do documento (disponível em meta.id) novoDoc["tipo"] = getTypeFromId(meta.id); // gerar um ID de documento para o documento transformado com base no tipo e no valor do atributo _id var id = generateId(novoDoc); registro("documento transformado (id = " + id + "): ", novoDoc); // gravar o documento transformado no bucket de destino com o ID gerado alvo[id] = novoDoc; } captura (e) { registro("erro ao transformar o documento" + meta.id + ". Consulte o balde de erros para obter mais detalhes."); // se houver algum erro, armazene a mensagem de erro no atributo error doc["error" (erro)] = e; // gravar o documento não transformado no compartimento de erros com o ID original erro[meta.id] = doc; } } função OnDelete(meta) { } // Essa é uma função recursiva que itera sobre todas as propriedades do documento (incluindo matrizes e subobjetos) // Ele transformará o JSON estendido em JSON padrão. função TransformValues(parentObj, parentProperty, obj) { var propertyType = ""; // para cada propriedade no objeto para (var propriedade em obj) { se (obj.hasOwnProperty(propriedade) && obj[propriedade] != nulo) { interruptor (propriedade) { caso "$oid": // converter parentObj.parentProperty = {"$oid": "3487634876"} // para parentObj.parentProperty = "3487634876" parentObj[parentProperty] = obj[propriedade]; quebra; caso "$date": se (obj["$date"]["$numberLong"] != nulo) { // converter parentObj.parentProperty = {"$date":{"$numberLong":"-2418768000000"}} // para parentObj.parentProperty = -2418768000000 parentObj[parentProperty] = Número(obj["$date"]["$numberLong"]); quebra; } // converter parentObj.parentProperty = {"$date": "1983-04-27T20:39:15Z"}} // para parentObj.parentProperty = "1983-04-27T20:39:15Z" parentObj[parentProperty] = obj["$date"]; quebra; caso "$numberInt": caso "$numberDecimal": caso "$numberLong": caso "$numberDouble": // converter parentObj.parentProperty = {"$numberInt": "1"} // para parentObj.parentProperty = 1 parentObj[parentProperty] = Número(obj[propriedade]); quebra; // !!! Essa função pode ser ampliada com a inclusão de instruções case adicionais aqui !!! padrão: // caso contrário, verifique o tipo de propriedade propertyType = determineType(obj[propriedade]); interruptor (propertyType) { caso "Objeto": // se a propriedade for um objeto, transformar recursivamente o objeto TransformValues(obj, propriedade, obj[propriedade]); quebra; caso "Matriz": // se a propriedade for uma matriz, transformar cada elemento da matriz transformArray(obj[propriedade]); quebra; padrão: // caso contrário, não faça nada quebra; } } } } retorno obj; } // Determinar o tipo do objeto especificado função determineType(obj) { retorno obj == nulo ? "null" : obj.construtor.nome; } // Transformar cada elemento da matriz especificada função transformArray(obj) { para (var i = 0; i < obj.comprimento; i++) { TransformValues(obj, i, obj[i]); } } // Obter o tipo de documento a partir do ID especificado. // Essa função espera que os documentos sejam importados com IDs no seguinte formato: // exemplo: :12 função getTypeFromId(id) { retorno id.dividir(":")[0]; } // Gerar um ID de documento para o documento especificado. // O novo ID será baseado no valor do atributo type e no valor do atributo _id: // : função generateId(documento) { var documentId = documento["_id"]; se (determineType(documentId) != "String" (Cadeia de caracteres)) { lançar "O valor '_id' deve ser uma cadeia de caracteres: _id = '" + documentId + "'"; } retorno documento["tipo"] + ":" + documentId; } |
Clique em Salvar para salvar o código e clique em < voltar para Eventing para voltar ao Eventos seção do console.
Você verá o novo transformar mas ele precisa ser implantado. Clique no ícone transformar e, em seguida, clique em Implementar.
Confirme a implementação da função com a configuração padrão clicando em Função de implantação.
Depois que a função for implementada, o status será implantado.
Agora tudo está pronto para importar os dados de exportação do MongoDB para o Couchbase e transformá-los em tempo real.
Importar documentos com o cbimport
Use o Utilitário cbimport para importar os arquivos de exportação do MongoDB. Antes de importar os dados, é importante entender a sintaxe do comando e o que ele está fazendo.
Aqui está um exemplo de comando cbimport:
1 |
$ cbimport json -c <agrupamento> -u <administrador nome de usuário> -p <administrador senha> -b <balde> -d <importação arquivo> -f <arquivo formato> -g <chave gerador> |
Para importar o MongoDB comentários execute o comando abaixo. Observe que o local do utilitário cbimport varia de acordo com o sistema operacional e está documentado aqui: Referência da CLI.
1 |
$ <path_to_cbimport>/cbimport json -c <agrupamento> -u <administrador nome de usuário> -p <administrador senha> -b de entrada -d arquivo:///comments.json -f list -g comment:#MONO_INCR# |
O comando se conectará ao cluster especificado (ou seja, -c couchbase://127.0.0.1) usando as credenciais de administrador fornecidas (ou seja, -u Administrator -p password).
O comando importará dados JSON de comments.json. Verifique o formato do arquivo comments.json exportado e especifique o opção de formato de conjunto de dados com base no formato do arquivo de exportação. Meu arquivo de exportação segue o formato formato de lista que contém uma única lista JSON em que cada elemento da lista representa um documento separado (-f list).
Os documentos são gravados no bucket de entrada (-b incoming) usando uma chave gerada usando o formato especificado (-g comment:#MONO_INCR#). Nesse comando, o formato especifica que cada chave de documento começará com "comment:". A chave Função MONO_INCR aumenta em 1 cada vez que é chamado, de modo que as chaves resultantes são comment:1, comment:2, etc.
Após a conclusão, você verá o seguinte resultado:
1 2 |
Json `arquivo://comments.json` importado para `http://127.0.0.1:8091` com sucesso. Documentos importado: 50304 Documentos falhou: 0 |
Ir para o Baldes e confirme que o sample_mflix O balde contém 50.304 documentos.
Para importar o MongoDB filmes execute o comando abaixo.
1 |
$ <path_to_cbimport>/cbimport json -c <agrupamento> -u <administrador nome de usuário> -p <administrador senha> -b de entrada -d arquivo:///movies.json -f list -g movie:#MONO_INCR# |
Após a conclusão, você verá o seguinte resultado:
1 2 |
Json `arquivo://movies.json` importado para `http://127.0.0.1:8091` com sucesso. Documentos importado: 23539 Documentos falhou: 0 |
Ir para o Baldes e confirme que o sample_mflix O balde contém 73.843 documentos.
Agora, verifique dois dos documentos transformados. Vá para o documento Documentos e certifique-se de que a seção Balde é definido como sample_mflix. Clique em id comment:5a9427648b0beebeb69579cc (o primeiro documento da lista):
Observe o conteúdo:
1 2 3 4 5 6 7 8 9 |
{ "_id": "5a9427648b0beebeb69579cc", "name" (nome): "Andrea Le", "email": "andrea_le@fakegmail.com", "movie_id": "573a1390f29313caabcd418c", "texto": "Rem officiis eaque repellendus amet eos doloribus. Porro dolor voluptatum voluptates neque culpa molestias. Voluptate unde nulla temporibus ullam.", "data": "2012-03-26T23:20:16Z", "tipo": "comentário" } |
Comparando-o com os dados exportados (procure por 5a9427648b0beebeb69579cc em comments.json):
1 2 3 4 5 6 7 8 |
{ "_id":{"$oid":"5a9427648b0beebeb69579cc"}, "name" (nome):"Andrea Le", "email":"andrea_le@fakegmail.com", "movie_id":{"$oid":"573a1390f29313caabcd418c"}, "texto":"Rem officiis eaque repellendus amet eos doloribus. Porro dolor voluptatum voluptates neque culpa molestias. Voluptate unde nulla temporibus ullam.", "data": {"$date": "2012-03-26T23:20:16Z"} } |
A função de transformação alterou os valores Extended JSON _id, movie_id e date. Observe que um atributo de tipo foi adicionado com base no prefixo da chave do documento (lembre-se de que especificamos comentário como o prefixo da chave ao importar os dados).
Feche o editor de documentos quando terminar de revisar o conteúdo do documento.
No ID do documento campo enter movie:573a1390f29313caabcd4135, clique em Recuperar documentose clique em id movie:573a1390f29313caabcd4135.
Observe o conteúdo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
{ "_id": "573a1390f29313caabcd4135", "plot": "Três homens martelam em uma bigorna...", "gêneros": [ "Curto" ], "tempo de execução": 1, "cast": [ "Charles Kayser", "John Ott" ], "num_mflix_comments": 1, "título": "Cena do ferreiro", "fullplot": "Uma câmera fixa olha para uma bigorna grande...", "países": [ "EUA" ], "liberado": -2418768000000, "diretores": [ "William K.L. Dickson" ], "classificado": "NÃO RATADO", "prêmios": { "ganha": 1, "nomeações": 0, "texto": "1 vitória." }, "lastupdated": "2015-08-26 00:03:50.133000000", "ano": 1893, "imdb": { "classificação": 6.2, "votos": 1189, "id": 5 }, "tipo": "filme", "tomates": { "visualizador": { "classificação": 3, "numReviews": 184, "medidor": 32 }, "lastUpdated": "2015-06-28T18:34:09Z" } } |
Comparando-o com os dados exportados (procure por 573a1390f29313caabcd4135 em movies.json):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
{ "_id": {"$oid": "573a1390f29313caabcd4135"}, "plot": "Três homens martelam em um ...", "gêneros": [ "Curto" ], "tempo de execução": 1, "cast": [ "Charles Kayser", "John Ott" ], "num_mflix_comments": 1, "título": "Cena do ferreiro", "fullplot": "Uma câmera fixa olha para uma bigorna grande...", "países": [ "EUA" ], "liberado": {"$date": {"$numberLong": "-2418768000000"}}, "diretores":[ "William K.L. Dickson" ], "classificado": "NÃO RATADO", "prêmios": { "ganha": 1, "nomeações": 0, "texto": "1 vitória." }, "lastupdated": "2015-08-26 00:03:50.133000000", "ano": 1893, "imdb": { "classificação": 6.2, "votos": 1189, "id": 5 }, "tipo": "filme", "tomates": { "visualizador": { "classificação": 3, "numReviews" 184, "medidor": 32 }, "lastUpdated": {"$date": "2015-06-28T18:34:09Z"} } } |
A função de transformação alterou os valores Extended JSON _id, released e tomatoes.lastUpdated. Observe que um atributo de tipo não foi adicionado nesse caso. O documento exportado já continha um atributo de tipo, portanto, a função de transformação não adicionou um, mas definiu o valor com base no prefixo da chave (lembre-se de que especificamos movie como o prefixo da chave ao importar os dados).
Feche o editor de documentos quando terminar de revisar o conteúdo do documento.
O que vem a seguir
Se você não planeja importar mais dados de exportação do MongoDB, pode cancelar a implantação da função de transformação e remover os buckets de entrada e de erro.
-
- Um artigo futuro abordará como atualizar o código do cliente existente para usar o SDK do Couchbase.
- Aproveite nosso treinamento on-line gratuito, disponível em https://learn.couchbase.com para saber mais sobre o Couchbase.
- Confira os vários IDEs para desenvolvedores do Couchbase - JetBrains, VSCodepara os quais temos plug-ins.
Para obter informações detalhadas sobre os diferentes modelos de documentos entre o Couchbase e o MongoDB, a modelagem de dados e o esquema do MongoDB e outras formas de comparar o MongoDB com o Couchbase, consulte este documento: Couchbase: Melhor que o MongoDB em todos os sentidos.
Saiba por que outras empresas escolhem o Couchbase em vez do MongoDB: