pipelines d’agrégation de MongoDB. Ce choix peut sembler naturel selon votre organisation. Il suppose que les développeurs ont des compétences en statistiques, analyses et visualisations de données; ou que les analystes soient de bons développeurs : cette combinaison de compétences est assez rare. En pratique, cette solution immédiate restreint vos données à une classe limitée d'utilisateurs et d'usages.
Une autre réponse est d’utiliser la solution de MongoDB Enterprise : MongoDB Connector for BI. Son principe est d’exposer une interface SQL devant MongoDB, en convertissant à la volée les requêtes et les résultats (cf la documentation et notre schéma ci-dessous). L’intérêt de cette solution est qu’elle est officielle et supportée. Elle permet notamment d’y connecter l’outil de BI commercial Tableau.
Le principal inconvénient de MongoDB Connector for BI est que son intégration est limitée. Il est possible d'y connecter un client MySQL, Tableau ou Qlik Sense, mais vous rencontrerez certainement des difficultés pour connecter d'autres outils (ex Superset). Par ailleurs, ce connecteur nécessite l’achat d’une licence MongoDB Entreprise. Enfin, le traitement des requêtes se fait en boîte noire. Il sera par conséquent difficile d’optimiser les requêtes en cas de performances insuffisantes.
Description du fonctionnement de MongoDB Connector for BI
Une dernière alternative est d’utiliser un outil ETL capable de synchroniser les données de MongoDB vers une base relationnelle. Nous avons par exemple identifié StichData et Talend, mais n’avons pas réalisé une étude exhaustive. Ces outils fonctionnent sur le même principe que notre solution open-source, et nécessitent des étapes similaires. Ils n’utilisent pas la brique mongo-connector, et réimplémentent des mécanismes de réplication. StichData propose par exemple une synchronisation par micro-batch, en s’appuyant sur une clé de réplication.
Au cours d’une mission, nous avons été confrontés à la séparation entre les mondes parallèles de l’analyste et du développeur. Pour passer d’un monde à l’autre, nous avons entrepris de développer une solution open-source permettant d’utiliser les outils d’analyses habituels sur des données issues d’une base MongoDB.
Le principe ? Synchroniser en temps réel la base MongoDB vers une base PostgreSQL. Cette dernière pourra être utilisée comme data warehouse, sur laquelle connecter des outils d’analyse de données.
Derrière la simplicité apparente de la solution annoncée se cache la complexité de la transition entre deux structures de données foncièrement différentes. Il est en effet nécessaire de désimbriquer un modèle de données qui n’est pas connu a priori.
Pour ce faire, nous avons eu recours à trois briques open-source complémentaires :
mongo-connector est donc la brique principale, qui synchronise la base MongoDB source vers une base cible.
Le fonctionnement est similaire à la synchronisation d’un membre du replica set. Une première phase de remplissage est réalisée via un transfert complet des collections de la base source. La synchronisation en temps réel est ensuite assurée par la lecture continue du fichier oplog, qui stocke les dernières modifications.
La brique mongo-connector est agnostique de la base cible vers laquelle elle propage des modifications. Pour traduire les instructions dans le langage cible, elle utilise une librairie dédiée selon la base, appelée “doc-manager”. Des doc-manager sont déjà intégrés pour des bases cibles NoSQL : MongoDB bien sûr, mais aussi SolR et ElasticSearch.
Malt a développé un doc manager pour PostgreSQL - mongo-connector-postgresql -, auquel nous avons contribué en ajoutant des tests et en corrigeant des bugs. Cet outil écrit des requêtes SQL pour propager les instructions des modification de Mongo. La complexité réside dans le fait qu’il faille passer de la structure imbriquée des données de MongoDB vers une forme relationnelle.
Passage d’une structure imbriquée à une structure relationnelle
Ce travail nécessite notamment de transformer les listes imbriquées (de valeurs ou d’objets) en des tables liées. Cette correspondance entre les structures Mongo et Postgres est spécifiée par l’utilisateur, via un fichier mapping.json.
Ce fichier de mapping peut être écrit à la main. Cela nécessite toutefois de :
Ce processus manuel est long, source d’erreur et difficile à maintenir. En conséquence, nous avons développé la brique pymongo-schema, qui permet d’automatiser la génération de ce fichier de mapping.
Pymongo-schema s’utilise en 2 étapes :
Sans parler d’analyse de données, ce schéma est très utile pour connaître l’état d’une base MongoDB. Pymongo-schema peut s’utiliser indépendamment pour cette seule fonctionnalité. Des formats de sortie variés sont d’ailleurs proposés pour ce fichier : json, csv, excel, markdown ou encore html.
La combinaison de ces trois briques permet de créer un pipeline assurant la synchronisation d’une base MongoDB vers une base PostgreSQL. Il est alors facile d'y analyser vos données, avec n'importe quel langage de programmation ou outil de BI.
Dans notre optique de présenter une solution totalement open-source lors de la conférence PyParis 2017, nous avons choisi l’outil Superset, open-sourcé par AirBnB et incubé désormais par la fondation Apache. La dernière partie de la vidéo de la conférence (ici) permet de visualiser un exemple simpliste du résultat obtenu.
Schéma de la solution complète
Cette solution est aujourd’hui mise en production au sein d’une de nos missions et est régulièrement enrichie de nouvelles fonctionnalités. Nous souhaitions donc partager notre travail avec la communauté en espérant faciliter ainsi l’analyse de données issues de bases MongoDB.
Certains axes d’amélioration subsistent encore. Tout d’abord, nous manquons de retour d’expérience d’autres utilisateurs, afin notamment d’améliorer la documentation.
Ensuite, cette solution ne permet pas de suivre automatiquement les évolutions du modèle de données dans MongoDB. Il est nécessaire de définir un nouveau mapping et de réinitialiser la synchronisation. Dans le cadre particulier du projet pour lequel nous avons développé cette solution, un script nous permet d’extraire le modèle de données directement depuis le code de notre application. Cette brique est malheureusement spécifique à MongoEngine et à cette application.
Un autre enjeu est de passer à l’échelle sur de plus gros volumes. Il serait notamment facile d’accélérer le travail de pymongo-schema, en ne parcourant qu’une partie des données tel que le fait variety. Nous n’avons cependant pas rencontré ce besoin dans notre projet et n’avons donc pas développé ces fonctions.
Toute réutilisation et toute contribution sont bienvenues. Pull-Requests are welcomed :)
Ce travail a été réalisé grâce aux précieuses collaborations de Thomas Weiss, David Delassus (Scille) et Julie Rossi (Scille).
Article de Hugo Lassiege, CTO de Malt, qui a initié mongo-connector-postgresql
Article de Maxime Gaudin, mainteneur à Malt de mongo-connector-postgresql
Bonne explication du problème de l’analytics on MongoDB par MongoDB au début de cette page
Cet excellent article détaille ce qui a fait le succès de SQL voici plus de 40 ans, et pourquoi il revient en force aujourd’hui
Article sur la notion de frontière dans les SI, qui explique l'intérêt générique de réutiliser SQL, et le risque de "mentir" en exposant une interface SQL devant une base NoSQL
Répertoires Github
Support de la présentation à Pyparis 2017 : lien
Vidéo de la présentation à Pyparis 2017 : lien