I Introduction
Exemple de scripts en JavaScript stocké sous forme de fonctions dans MongoDB.
La base de données utilisée est téléchargeable à partir de l’adresse suivante : http://world.openfoodfacts.org/data/openfoodfacts-mongodbdump.tar.gz
L’outil utilisé pour stocker les fonctions js en base de données est le client Robomongo (plus pratique qu’en shell)
II Exemple de script
II.1 Recherche de documents
Rechercher tous les documents en fonction d’une marque puis n’afficher que certaines propriétés :
fonction :
[pastacode lang= »javascript » manual= »function(_marque)%20%7B%0A%20%20%20%20var%20_var_marque%20%3D%20_marque%3B%0A%20%20%20%20%2F%2F%20S%C3%A9lection%20de%20la%20base%20donn%C3%A9es%20de%20travail%0A%20%20%20%20var%20db_food%20%3D%20db.getSiblingDB(‘open_food_facts’)%0A%20%20%20%20%2F%2F%20Recherche%20document%0A%20%20%20%20var%20cursor%20%3D%20db_food.produit.find(%7Bbrands%20%3A%20_var_marque%20%7D)%3B%0A%20%20%20%20%2F%2F%20NB%20r%C3%A9sultat%0A%20%20%20%20var%20nb_resultat%20%3D%20%20cursor.count()%3B%0A%20%20%20%20var%20texte%20%3D%20%22%22%3B%0A%20%20%20%20var%20cpt%20%3D%200%3B%0A%20%20%20%20%2F%2F%20Parcours%20du%20r%C3%A9sultat%0A%20%20%20%20while%20(%20cursor.hasNext()%20)%20%7B%0A%20%20%20%20%20%20%20%2F%2F%20r%C3%A9cup%C3%A8re%20le%20document%20en%20cours%0A%20%20%20%20%20%20%20var%20doc%20%3D%20cursor.next()%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20construit%20r%C3%A9sultat%20texte%0A%20%20%20%20%20%20%20texte%20%2B%3D%20cpt%20%2B%20%22%20–%3E%22%20%2B%20doc.brands%20%2B%20%22%20%3A%20%22%20%2B%20doc.product_name%20%2B%20%22%5Cn%22%3B%0A%20%20%20%20%20%20%20cpt%20%2B%2B%3B%0A%20%20%20%20%7D%20%0A%20%20%20%20%2F%2F%20Affichage%20r%C3%A9sultat%20texte%0A%20%20%20%20texte%20%3D%20%22nb%20r%C3%A9sultats%20%3A%22%20%2B%20nb_resultat%20%2B%20%22%5Cn%22%20%2B%20texte%3B%0A%20%20%20%20print(texte)%3B%0A%7D » message= » » highlight= » » provider= »manual »/]
Résultat :
> db.loadServerScripts() > recherche1("lustucru") nb résultats :5 0 -->lustucru : cubes à poêler 1 -->lustucru : pasta box lustucru fusilli bolo poulet 2 -->lustucru : Mafalda comme un chef 3 -->lustucru : Polenta facile saveur Fromage 4 -->lustucru : Oufs bio gros >
II.2 Copie locale d’une base de données
II.2.1 Copie manuelle
[pastacode lang= »javascript » manual= »%20%20%20%20var%20nom_bdd_source%20%3D%20%22open_food_facts%22%20%3B%0A%20%20%20%20var%20nom_bdd_dest%20%20%20%3D%20%22open_food_facts2%22%3B%0A%20%20%20%20%0A%20%20%20%20var%20nom_col_source%20%3D%20%22produit%22%20%3B%0A%20%20%20%20var%20nom_col_dest%20%20%20%3D%20%22test_clone2%22%20%3B%0A%20%20%20%0A%0A%20%20%20%20print(%22–%3E%20d%C3%A9but%20%3A%20%22%20%2B%20new%20Date()%20)%3B%0A%20%20%20%0A%20%20%20%20%2F%2F%20S%C3%A9lection%20BDD%0A%20%20%20%20var%20db_source%20%3D%20db.getSiblingDB(nom_bdd_source)%3B%0A%20%20%20%20var%20db_dest%20%20%20%3D%20db.getSiblingDB(nom_bdd_dest)%3B%0A%20%20%20%20%2F%2F%20Obj%20Collection%0A%20%20%20%20var%20col_source%20%3D%20%20db_source.getCollection(nom_col_source)%3B%0A%20%20%20%20var%20col_dest%20%20%20%3D%20%20db_dest.getCollection(nom_col_dest)%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20!!%20Efface%20la%20collection%20de%20destination%0A%20%20%20%20col_dest.drop()%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20recherche%20tous%20les%20documents%0A%20%20%20%20var%20cursor_col_source%20%3D%20col_source.find(%7B%7D)%3B%0A%20%20%20%20%2F%2F%20parcours%20r%C3%A9sultat%0A%20%20%20%20while%20(cursor_col_source.hasNext())%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20r%C3%A9cup%C3%A8re%20doc%0A%20%20%20%20%20%20%20%20var%20doc%20%3D%20cursor_col_source.next()%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20deb%20traitement%0A%20%20%20%20%20%20%20%20%2F%2F%20….%0A%20%20%20%20%20%20%20%20%2F%2F%20fin%20traitement%0A%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20ins%C3%A8re%20doc%20dans%20nouvelle%20collection%0A%20%20%20%20%20%20%20%20var%20res%20%3D%20col_dest.insert(doc)%3B%0A%0A%20%20%20%20%7D%20%20%20%20%0A%20%20%20%0A%20%20%20%20db_source.logout()%3B%20%0A%20%20%20%20db_dest.logout()%3B%20%0A%20%20%20%20%0A%20%20%20%20print(%22–%3E%20fin%20%3A%20%22%20%2B%20new%20Date()%20)%3B%20%20%0A%20%20″ message= » » highlight= » » provider= »manual »/]
Résultat :
> clone_collection() --> début : Wed Feb 15 2017 18:50:57 GMT+0100 --> fin : Wed Feb 15 2017 18:58:51 GMT+0100 >
Pour 131452 documents (complexes) d’une taille total d’environ 1,5 GO de données. Et sur un PC I7, 8Go de RAM et disque SSD.
II.2.2 Copie automatique
Il existe la fonction « Copyto » mais elle est dépréciée depuis la version 3 (lien).
Donc il reste l’import/export (mongoexport / mongoimport) mais ce n’est pas du javascript …
PS C:\Program Files\MongoDB\Server\3.4\bin> .\mongoexport.exe -d "open_food_facts" -c "produit" | .\mongoimport.exe -d "import_test" -c "produit_copie"
Mais ce type de commande en pipeline nécessite de la ram sinon :
2017-02-15T19:45:39.671+0100 import_test.produit_copie 0B 2017-02-15T19:45:42.671+0100 import_test.produit_copie 0B Échec de l'exécution du programme « mongoimport.exe » : Une exception de type 'System.OutOfMemoryException' a été levée . Au niveau de ligne : 1 Caractère : 72 + .\mongoexport.exe -d "open_food_facts" -c "produit" | .\mongoimport.exe <<<< -d "import_test" -c "produit_copie" . Au niveau de ligne : 1 Caractère : 1 + <<<< .\mongoexport.exe -d "open_food_facts" -c "produit" | .\mongoimport.exe -d "import_test" -c "produit_copie" + CategoryInfo : ResourceUnavailable: (:) [], ApplicationFailedException + FullyQualifiedErrorId : NativeCommandFailed
Donc allons y à la main !
Export de la collection :
.\mongoexport.exe -d "open_food_facts" -c "produit" -o D:\mongodb\export.json
Durée export : 6 mn.
Import de la collection :
.\mongoimport.exe -d "import_test" -c "produit_copie" --file D:\mongodb\export.json
durée Import : 2mn 15s …
Bilan : 8mn environ comme en Javascript !
Remarque importante : les indexs ne sont pas copiés !!! Il faut passer par un dump et non un export si l’on veut tout copier (index,etc.).
III Export de données dans un fichier texte
Il n’est pas possible de faire un export directement en Javascript. Mais il est possible de rediriger l’écriture console vers un fichier. Donc l’opération sera l’éxecution d’un script js en ligne de commande par le client mongo.
Le script ci-dessous parcourt l’ensemble des documents et en extrait certaines propriétés ou en calcule d’autres.
[pastacode lang= »javascript » manual= »%2F%2Fselection%20de%20la%20base%20de%20donn%C3%A9es%0Avar%20db_food%20%3D%20db.getSiblingDB(‘open_food_facts’)%0A%0Avar%20critere_recherche%20%3D%20%7B%7D%3B%0Avar%20tab_champs_remontee%20%3D%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20_id%3A1%2C%0A%20%20%20%20%20%20%20%20brands%3A1%2C%0A%20%20%20%20%20%20%20%20complete%3A1%2C%0A%20%20%20%20%20%20%20%20product_name%3A1%2C%0A%20%20%20%20%20%20%20%20quantity%3A1%2C%0A%20%20%20%20%20%20%20%20images%3A1%2C%0A%20%20%20%20%20%20%20%20ingredients_text%3A1%2C%0A%20%20%20%20%20%20%20%20scans_n%3A1%0A%20%20%20%20%20%7D%3B%0A%0Avar%20prefixe_url_image%20%3D%20%22https%3A%2F%2Fstatic.openfoodfacts.org%2Fimages%2Fproducts%2F%22%3B%0A%0A%2F%2F%20lancer%20la%20recherche%0Avar%20curseur%20%3D%20db_food.produit.find(%20critere_recherche%2C%20tab_champs_remontee)%3B%0A%0Avar%20texte%20%3D%20%22%22%3B%0Avar%20sep%20%20%20%3D%20%22%5Ct%22%3B%0Avar%20cpt%20%20%20%3D%200%3B%0A%2F%2F%20Parcours%20du%20r%C3%A9sultat%0Awhile%20(%20curseur.hasNext()%20)%20%7B%0A%20%20%20%20%2F%2F%20r%C3%A9cup%C3%A8re%20le%20document%20en%20cours%0A%20%20%20%20var%20doc%20%3D%20curseur.next()%3B%0A%20%20%20%20%0A%20%20%20%20var%20brands%20%20%20%20%20%20%20%20%20%20%20%3D%20%22%3F%22%3B%20%20%2F%2F%20marque%0A%20%20%20%20var%20complete%20%20%20%20%20%20%20%20%20%3D%20%22%3F%22%3B%20%20%2F%2F%20fiche%20complete%0A%20%20%20%20var%20product_name%20%20%20%20%20%3D%20%22%3F%22%3B%20%20%2F%2F%20nom%20produit%0A%20%20%20%20var%20quantity%20%20%20%20%20%20%20%20%20%3D%20%22%3F%22%3B%20%20%2F%2F%20poids%20%0A%20%20%20%20var%20ingredients_text%20%3D%20%22%3F%22%3B%20%20%2F%2F%20ingr%C3%A9dient%0A%20%20%20%20var%20rev%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%22%3F%22%3B%20%20%20%2F%2F%20version%20image%0A%20%20%20%20var%20size_100%20%20%20%20%20%20%20%20%20%3D%20false%3B%20%2F%2F%20image%20en%20100%0A%20%20%20%20var%20size_200%20%20%20%20%20%20%20%20%20%3D%20false%3B%20%2F%2F%20image%20en%20200%0A%20%20%20%20var%20size_400%20%20%20%20%20%20%20%20%20%3D%20false%3B%20%2F%2F%20image%20en%20400%20%20%0A%20%0A%20%20%20%20var%20url_image%20%20%20%20%20%20%20%20%3D%20%22%3F%22%3B%0A%20%20%20%20%0A%20%20%20%20var%20ligne%20%3D%20%22%22%3B%0A%0A%20%20%20%20%2F%2F%20——————————-%0A%20%20%20%20%2F%2F%20r%C3%A9cup%C3%A9ration%20propriet%C3%A9s%20simples%0A%20%20%20%20if%20(%20doc.hasOwnProperty(‘brands’))%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20brands%20%20%20%20%20%20%20%20%20%20%20%20%3D%20doc.brands%3B%20%7D%0A%20%20%20%20if%20(%20doc.hasOwnProperty(‘complete’))%20%20%20%20%20%20%20%20%20%20%20%7B%20complete%20%20%20%20%20%20%20%20%20%20%3D%20doc.complete%3B%20%7D%0A%20%20%20%20if%20(%20doc.hasOwnProperty(‘product_name’))%20%20%20%20%20%20%20%7B%20product_name%20%20%20%20%20%20%3D%20doc.product_name%3B%20%7D%0A%20%20%20%20if%20(%20doc.hasOwnProperty(‘quantity’))%20%20%20%20%20%20%20%20%20%20%20%7B%20quantity%20%20%20%20%20%20%20%20%20%20%3D%20doc.quantity%3B%20%7D%0A%20%20%20%20if%20(%20doc.hasOwnProperty(‘ingredients_text’))%20%20%20%7B%20ingredients_text%20%20%3D%20doc.ingredients_text%3B%20%7D%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%2F%2F%20—————————-%0A%20%20%20%20%2F%2F%20cherche%20si%20image%20scan%20existe%0A%20%20%20%20if(doc.images)%7B%0A%20%20%20%20%20%20if%20(doc.images.front_fr)%20%7B%0A%20%20%20%20%20%20%20%20%20%20if%20(doc.images.front_fr.hasOwnProperty(‘rev’))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20A%20ce%20stade%20un%20num%C3%A9ro%20de%20r%C3%A9vision%20existe%20!%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20rev%20%3D%20doc.images.front_fr.rev%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20if%20(doc.images.front_fr.sizes)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(doc.images.front_fr.sizes%5B100%5D)%20%7B%20size_100%20%3D%20true%3B%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(doc.images.front_fr.sizes%5B200%5D)%20%7B%20size_200%20%3D%20true%3B%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(doc.images.front_fr.sizes%5B400%5D)%20%7B%20size_400%20%3D%20true%3B%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20—————————————————-%0A%20%20%20%20%2F%2F%20scan%20existe%20–%3E%20construction%20du%20chemin%20pour%20y%20acc%C3%A9der%0A%20%20%20%20if%20(size_100)%20%7B%0A%20%20%20%20%20%20%20%20var%20numero%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20code%20barre%20%C3%A0%208%20chiffres%0A%20%20%20%20%20%20%20%20if%20(doc._id.length%3D%3D8)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20numero%20%3D%20doc._id%20%2B%20%22%2F%22%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%2F%2F%20code%20barre%20%C3%A0%2013%20chiffres%0A%20%20%20%20%20%20%20%20if%20(doc._id.length%3D%3D13)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20numero%20%3D%20doc._id.substr(0%2C3)%20%2B%20%22%2F%22%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20numero%20%2B%3D%20doc._id.substr(3%2C3)%20%2B%20%22%2F%22%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20numero%20%2B%3D%20doc._id.substr(6%2C3)%20%2B%20%22%2F%22%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20numero%20%2B%3D%20doc._id.substr(9%2C4)%20%2B%20%22%2F%22%20%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20url_image%20%3D%20prefixe_url_image%20%2B%20numero%20%2B%20%22front_fr.%22%20%2B%20rev%20%2B%20%22.100.jpg%22%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F——————————-%0A%20%20%20%20%2F%2F%20Construction%20ligne%20export%0A%0A%20%20%20%20ligne%20%2B%3D%20cpt%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20doc._id%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20brands%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20complete%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20product_name%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20quantity%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20ingredients_text%20%2B%20sep%3B%20%20%20%0A%20%20%20%20ligne%20%2B%3D%20rev%20%2B%20sep%3B%20%20%20%20%20%20%0A%20%20%20%20ligne%20%2B%3D%20size_100%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20size_200%20%2B%20sep%3B%0A%20%20%20%20ligne%20%2B%3D%20size_400%20%2B%20sep%3B%20%20%20%20%0A%2F%2F%20%20%20%20ligne%20%2B%3D%20url_image%20%2B%20sep%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20suppression%20des%20retours%20chariots%0A%20%20%20%20ligne%20%3D%20ligne.replace(new%20RegExp(%22%5Cn%22%2C%20’g’)%20%2C%22%22)%3B%0A%20%20%20%20ligne%20%3D%20ligne.replace(new%20RegExp(%22%5Cr%22%2C%20’g’)%20%2C%22%22)%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20affichage%20r%C3%A9sultat%0A%20%20%20%20print(ligne)%3B%0A%20%20%20%20%0A%20%20%20%20cpt%20%2B%2B%3B%0A%7D%0A%0A%2F%2F%20deconnexion%0Avar%20res%20%3D%20db_food.logout()%3B%0A%0A » message= » » highlight= » » provider= »manual »/]
Lancement du script :
Supposons que le script soit stocké dans le chemin suivant : D:\mongodb\data\script\export_data.js
Alors la ligne de commande sera :
PS C:\Program Files\MongoDB\Server\3.4\bin> .\mongo.exe 127.0.0.1/open_food_facts D:\mongodb\data\script\export_data.js > D:\mongodb\data\script\export_data.txt
Pour éviter d’avoir ces lignes en début de fichier :
MongoDB shell version v3.4.2 connecting to: mongodb://127.0.0.1/open_food_facts MongoDB server version: 3.4.2 0 3560070764945 Carrefour 1 Boudin noir aux pommes ├á l'ancienne 250 g Sang frais de porc, gras de porc, pur├®e de pommes 11 %, d├®s de pommes 10 %, oignon, t├¬te de porc cuite, _lait_, couenne de porc, sucre, sel, poivre gris, cannelle, enveloppe : boyau naturel de porc. 6 true true true 1 3560070765034 Carrefour 1 Boudin Noir aux oignons ├á l'ancienne 375 g Sang frais de porc, oignon 30 %, gras de porc, t├¬te de porc cuite, _lait_, sel, persil, poivre gris, m├®lange 4 ├®pices (cannelle, girofle, poivre, muscade), enveloppe : boyau naturel de porc. 6 true true true 2 3560070931385 Carrefour 0 Petit Beurre 130 g 6 true true true
Il faut ajouter l’option –quiet . Ce qui donne la commande suivante :
.\mongo.exe --quiet 127.0.0.1/open_food_facts D:\mongodb\data\script\export_data.js > D:\mongodb\data\script\export_data.txt