Comment synchroniser des données transformées de MongoDB vers Elasticsearch avec Transporter sur Ubuntu 16.04

introduction

Transporter est un outil à code source ouvert permettant de déplacer des données entre différents magasins de données. Les développeurs écrivent souvent des scripts uniques pour des tâches telles que le déplacement de données entre bases de données, le déplacement de données de fichiers vers une base de données, ou inversement, mais l’utilisation d’un outil tel que Transporter présente plusieurs avantages.

Dans Transporter, vous construisez pipelines, qui définissent le flux de données d’une source (où les données sont lues) à un sink (où les données sont écrites). Les sources et les puits peuvent être des bases de données SQL ou NoSQL, des fichiers à plat ou d’autres ressources. Transporter utilise adaptors, qui sont des extensions enfichables, pour communiquer avec ces ressources. Le projet inclut par défaut several adapters pour les bases de données populaires.

En plus du déplacement de données, Transporter vous permet également de modifier les données lors de leur déplacement dans un pipeline à l’aide d’un transformer. Comme les adaptateurs, il existe https://github.com/compose/transporter/wiki/Transformers&several transformers] inclus par défaut. Vous pouvez également écrire vos propres transformateurs pour personnaliser la modification de vos données.

Dans ce didacticiel, nous allons passer en revue un exemple de transfert et de traitement de données d’une base de données MongoDB vers Elasticsearch à l’aide des adaptateurs intégrés de Transporter et d’un transformateur personnalisé écrit en JavaScript.

Conditions préalables

Pour suivre ce tutoriel, vous aurez besoin de:

Les pipelines de transport sont écrits en JavaScript. Vous n’avez besoin d’aucune connaissance ou expérience préalable de JavaScript pour suivre ce didacticiel, mais vous pouvez en apprendre plus à l’adresse https://www.digitalocean.com/community/tags/javascript?type=tutorials=cette aide-mémoire JavaScript].

Étape 1 - Installation de Transporter

Transporter fournit des fichiers binaires pour les systèmes d’exploitation les plus courants. Le processus d’installation pour Ubuntu comporte deux étapes: télécharger le binaire Linux et le rendre exécutable.

Tout d’abord, obtenez le lien vers la dernière version à l’adresse La page des dernières versions deTransporter sur GitHub. Copiez le lien qui se termine par + -linux-amd64 +. Ce tutoriel utilise la version 0.5.2, qui est la plus récente au moment de la rédaction.

Téléchargez le binaire dans votre répertoire personnel.

cd
wget https://github.com/compose/transporter/releases/download/v/transporter--linux-amd64

Déplacez-le dans + / usr / local / bin + ou dans votre répertoire d’installation préféré.

mv transporter-*-linux-amd64 /usr/local/bin/transporter

Ensuite, rendez-le exécutable pour pouvoir l’exécuter.

chmod +x /usr/local/bin/

Vous pouvez tester que Transporter est configuré correctement en exécutant le fichier binaire.

transporter

Vous verrez la sortie de l’aide à l’utilisation et le numéro de version:

OutputUSAGE
 transporter <command> [flags]

COMMANDS
 run       run pipeline loaded from a file
 . . .

VERSION

Afin d’utiliser Transporter pour déplacer des données de MongoDB vers Elasticsearch, nous avons besoin de deux choses: les données dans MongoDB que nous voulons déplacer et un pipeline qui indique à Transporter comment le déplacer. L’étape suivante crée des exemples de données, mais si vous souhaitez déjà déplacer une base de données MongoDB, vous pouvez ignorer l’étape suivante et passer directement à l’étape 3.

Étape 2 - Ajout de données d’exemple à MongoDB (facultatif)

Dans cette étape, nous allons créer une base de données exemple avec une seule collection dans MongoDB et ajouter quelques documents à cette collection. Ensuite, dans le reste du didacticiel, nous allons migrer et transformer ces exemples de données avec un pipeline Transporter.

Commencez par vous connecter à votre base de données MongoDB.

mongo

Cela modifiera votre invite en + mongo> +, indiquant que vous utilisez le shell MongoDB.

À partir de là, sélectionnez une base de données sur laquelle travailler. Nous appellerons le nôtre "+ mon_application +".

use my_application

Dans + MongoDB +, vous n’avez pas besoin de créer explicitement une base de données ou une collection. Une fois que vous avez commencé à ajouter des données à une base de données que vous avez sélectionnée par son nom, cette base de données est automatiquement créée.

Donc, pour créer la base de données + my_application +, sauvegardez deux documents dans sa collection + users +: un représentant Sammy Shark et un représentant Gilly Glowfish. Ce seront nos données de test.

db.users.save({"firstName": "Sammy", "lastName": "Shark"});
db.users.save({"firstName": "Gilly", "lastName": "Glowfish"});

Après avoir ajouté les documents, vous pouvez interroger la collection + users + pour voir vos enregistrements.

db.users.find().pretty();

La sortie ressemblera à la sortie ci-dessous, mais les colonnes + _id + seront différentes. MongoDB ajoute automatiquement des ID d’objet pour identifier de manière unique les documents d’une collection.

output{
 "_id" : ObjectId("59299ac7f80b31254a916456"),
 "firstName" : "Sammy",
 "lastName" : "Shark"
}
{
 "_id" : ObjectId("59299ac7f80b31254a916457"),
 "firstName" : "Gilly",
 "lastName" : "Glowfish"
}

Appuyez sur + CTRL + C + pour quitter le shell MongoDB.

Ensuite, créons un pipeline Transporter pour déplacer ces données de MongoDB vers Elasticsearch.

Étape 3 - Création d’un pipeline de base

Un pipeline dans Transporter est défini par un fichier JavaScript nommé + pipeline.js + par défaut. La commande intégrée + init + crée un fichier de configuration de base] dans le répertoire correct, en fonction de la source et du récepteur.

Initialisez un démarreur + pipeline.js + avec MongoDB comme source et Elasticsearch comme récepteur.

transporter init mongodb elasticsearch

Vous verrez le résultat suivant:

OutputWriting pipeline.js...

Vous n’avez pas besoin de modifier + pipeline.js + pour cette étape, mais examinons pour voir comment cela fonctionne.

Le fichier ressemble à ceci, mais vous pouvez également afficher le contenu du fichier à l’aide de la commande + cat pipeline.js +, + less pipeline.js + (quittez + less + en appuyant sur + q +), ou par en l’ouvrant avec votre éditeur de texte préféré.

pipeline.js

var source = mongodb({
 "uri": "${MONGODB_URI}"
 // "timeout": "30s",
 // "tail": false,
 // "ssl": false,
 // "cacerts": ["/path/to/cert.pem"],
 // "wc": 1,
 // "fsync": false,
 // "bulk": false,
 // "collection_filters": "{}",
 // "read_preference": "Primary"
})

var sink = elasticsearch({
 "uri": "${ELASTICSEARCH_URI}"
 // "timeout": "10s", // defaults to 30s
 // "aws_access_key": "ABCDEF", // used for signing requests to AWS Elasticsearch service
 // "aws_access_secret": "ABCDEF" // used for signing requests to AWS Elasticsearch service
 // "parent_id": "elastic_parent" // defaults to "elastic_parent" parent identifier for Elasticsearch
})

t.Source("source", source, "/.*/").Save("sink", sink, "/.*/")

Les lignes commençant par + var source + et + var sink + définissent les variables JavaScript pour MongoDB et Adaptateurs Elasticsearch, respectivement. Nous définirons les variables d’environnement + MONGODB_URI + et + ELASTICSEARCH_URI + dont ces adaptateurs auront besoin plus tard dans cette étape.

Les lignes commençant par + // + sont des commentaires. Ils mettent en évidence certaines options de configuration courantes que vous pouvez définir pour votre pipeline, mais nous ne les utilisons pas pour le pipeline de base que nous créons ici.

La dernière ligne connecte la source et le récepteur. La variable + transporter + ou + t + nous permet d’accéder à notre pipeline. Nous utilisons les + .Source () + et + .Save () + functions pour ajouter la source et le puits en utilisant les variables + source + et + + puits + définies précédemment dans le fichier.

Le troisième argument des fonctions + Source () + et + Save () + est l’espace de nommage `+. données de MongoDB et enregistrez-les sous le même espace de noms dans Elasticsearch.

Avant de pouvoir exécuter ce pipeline, nous devons définir les https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux- vps [variables d’environnement] pour MongoDB URI et https://www.elastic.co/guide/fr/elasticsearch/reference/current/ modules-network.html [URI Elasticsearch]. Dans l’exemple que nous utilisons, les deux sont hébergés localement avec les paramètres par défaut, mais veillez à personnaliser ces options si vous utilisez des instances existantes de MongoDB ou Elasticsearch.

export MONGODB_URI='mongodb://localhost/my_application'
export ELASTICSEARCH_URI='http://localhost:9200/my_application'

Nous sommes maintenant prêts à exécuter le pipeline.

transporter run pipeline.js

Vous verrez une sortie qui se termine comme ceci:

Output. . .
INFO[0001] metrics source records: 2                     path=source ts=1522942118483391242
INFO[0001] metrics source/sink records: 2                path="source/sink" ts=1522942118483395960
INFO[0001] exit map[source:mongodb sink:elasticsearch]   ts=1522942118483396878

Dans les deuxième et troisième lignes, cette sortie indique qu’il y avait 2 enregistrements présents dans la source et que 2 enregistrements ont été déplacés vers le récepteur.

Pour confirmer que les deux enregistrements ont été traités, vous pouvez interroger Elasticsearch sur le contenu de la base de données + my_application +, qui devrait maintenant exister.

curl $ELASTICSEARCH_URI/_search?pretty=true

Le paramètre +? Pretty = true + facilite la lecture de la sortie:

Output{
 "took" : 5,
 "timed_out" : false,
 "_shards" : {
   "total" : 5,
   "successful" : 5,
   "skipped" : 0,
   "failed" : 0
 },
 "hits" : {
   "total" : 2,
   "max_score" : 1.0,
   "hits" : [
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e9c6687d9f638ced4fe",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Gilly",
         "lastName" : "Glowfish"
       }
     },
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e986687d9f638ced4fd",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Sammy",
         "lastName" : "Shark"
       }
     }
   ]
 }
}

Les bases de données et les collections dans MongoDB sont analogues aux index et aux types dans Elasticsearch. Dans cet esprit, vous devriez voir:

  • Le champ + _index + est défini sur + my_application, + le nom de la base de données MongoDB d’origine).

  • Le champ + _type + est défini sur + utilisateurs, + le nom de la collection MongoDB.

  • Les champs + firstName + et + lastName + ont été remplis avec «Sammy» «Shark» et «Gilly» «Glowfish», respectivement.

Cela confirme que les deux enregistrements de MongoDB ont été traités avec succès via Transporter et chargés dans Elasticsearch. Pour construire sur ce pipeline de base, nous ajouterons une étape de traitement intermédiaire capable de transformer les données en entrée.

Étape 4 - Création d’un transformateur

Comme son nom l’indique, transformers modifie les données source avant de les charger dans le récepteur. Par exemple, ils vous permettent d’ajouter un nouveau champ, de supprimer un champ ou de modifier les données d’un champ. Transporter est fourni avec des transformateurs prédéfinis et prend en charge les transformateurs personnalisés.

Généralement, les transformateurs personnalisés sont écrits en tant que fonctions JavaScript et enregistrés dans un fichier séparé. Pour les utiliser, vous ajoutez une référence au fichier de transformation dans + pipeline.js +. Transporter inclut à la fois les moteurs JavaScript Otto et Goja. Goja étant plus récent et généralement plus rapide, nous l’utiliserons ici. La seule différence fonctionnelle est la syntaxe.

Créez un fichier nommé + transform.js +, que nous utiliserons pour écrire notre fonction de transformation.

nano transform.js

Voici la fonction que nous allons utiliser, qui créera un nouveau champ appelé + nom complet +, dont la valeur sera les champs + prénom + + et + nom + + concaténés ensemble, séparés par un espace (comme + Sammy Shark + `).

transform.js

function transform(msg) {
   msg.data.fullName = msg.data.firstName + " " + msg.data.lastName;
   return msg
}

Parcourons les lignes de ce fichier:

  • La première ligne du fichier, + function transform (msg), + est la définition de https://www.digitalocean.com/community/tutorials/how-to-define-functions-in-javascript.

  • + msg + est un JavaScript objet qui contient les détails du document source. Nous utilisons cet objet pour access les données passant par le pipeline.

  • La première ligne de la fonction concatenates les deux champs existants et https: // www .digitalocean.com / community / tutorials / comprehension-objects-en-javascript # propriétés-ajout-et-modification-d’objet [attribue cette valeur] au nouveau champ + nom complet +.

  • La dernière ligne de la fonction renvoie le nouvel objet + msg + à utiliser pour le reste du pipeline.

Enregistrez et fermez le fichier.

Ensuite, nous devons modifier le pipeline pour utiliser ce transformateur. Ouvrez le fichier + pipeline.js + pour le modifier.

nano pipeline.js

Dans la dernière ligne, nous devons ajouter un appel à la fonction + Transform () + pour ajouter le transformateur au pipeline entre les appels à + ​​Source () + et + Save () +, comme ceci :

~ / transporteur / pipeline.js

. . .
t.Source("source", source, "/.*/")

.Save("sink", sink, "/.*/")

L’argument passé à + ​​Transform () + est le type de transformation, qui est Goja dans ce cas. En utilisant la fonction + goja +, nous spécifions le nom du fichier du transformateur en utilisant son https://www.digitalocean.com/community/tutorials/basic-linux-navigation-and-file-management#moving-around-the- système de fichiers avec quot-cd-quot [chemin relatif].

Enregistrez et fermez le fichier. Avant de réexécuter le pipeline pour tester le transformateur, effaçons les données existantes dans Elasticsearch du test précédent.

curl -XDELETE $ELASTICSEARCH_URI

Vous verrez cette sortie reconnaître le succès de la commande.

Output{"acknowledged":true}

Maintenant, réexécutez le pipeline.

transporter run pipeline.js

La sortie ressemblera beaucoup au test précédent et vous pourrez voir dans les dernières lignes si le pipeline s’est terminé avec succès comme auparavant. Pour être sûr, nous pouvons à nouveau vérifier Elasticsearch pour voir si les données existent dans le format que nous attendons.

curl $ELASTICSEARCH_URI/_search?pretty=true

Vous pouvez voir le champ + nom complet + dans la nouvelle sortie:

Output{
 "took" : 9,
 "timed_out" : false,
 "_shards" : {
   "total" : 5,
   "successful" : 5,
   "skipped" : 0,
   "failed" : 0
 },
 "hits" : {
   "total" : 2,
   "max_score" : 1.0,
   "hits" : [
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e9c6687d9f638ced4fe",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Gilly",

         "lastName" : "Glowfish"
       }
     },
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e986687d9f638ced4fd",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Sammy",

         "lastName" : "Shark"
       }
     }
   ]
 }
}

Notez que le champ + nom complet + a été ajouté dans les deux documents avec les valeurs correctement définies. Grâce à cela, nous savons maintenant comment ajouter des transformations personnalisées à un pipeline Transporter.

Conclusion

Vous avez créé un pipeline Transporter de base avec un transformateur pour copier et modifier les données de MongoDB vers Elasticsearch. Vous pouvez appliquer des transformations plus complexes de la même manière, en chaînant plusieurs transformations dans le même pipeline, etc. MongoDB et Elasticsearch ne sont que deux des adaptateurs pris en charge par Transporter. Il prend également en charge les fichiers plats, les bases de données SQL telles que Postgres et de nombreuses autres sources de données.

Vous pouvez consulter le projet Transporter sur GitHub pour rester à jour des dernières modifications apportées à l’API et visiter the. Wiki Transporter pour plus d’informations sur l’utilisation des adaptateurs, des transformateurs et des autres fonctionnalités de Transformer.