web-dev-qa-db-fra.com

comment importer des données dans mongodb à partir du serveur sql?

comment importer des données dans mongodb à partir du serveur sql?

j'ai ces tables dans la base de données SQL avec les colonnes suivantes

États, villes, zones urbaines

 États 
 Nom d'ID 
 
 Villes 
 Nom d'ID StatesId 
 
 CitiArea 
 
 Identifiant Nom CityId 
 

et je veux des données dans mongoDb Like.

 
 {
 État: "Orissa", 
 Villes: {
 CitiName: "Phulbani", 
 CitYArea: {
 "Phulbani", "Phulbani2", "Pokali", "Madira" 
} 
} 
} 
 

existe-t-il des outils ou dois-je écrire du code pour cette transformation de données?

15
Deepak

Il existe plusieurs façons possibles d'aborder cela en écrivant du code dans la langue de votre choix en utilisant les API appropriées pour sélectionner les données, les transformer puis les insérer dans MongoDB.

Vous pouvez également le faire en utilisant SQL, le langage de requête MongoDB et le Shell. Une façon simple consiste à sélectionner des données plates via SQL, à les vider dans un fichier CSV, à les importer dans MongoDB et à utiliser le cadre d'agrégation pour les transformer au format souhaité.

Si vous avez la chance d'utiliser une base de données qui prend en charge les tableaux ou d'autres façons de regrouper les lignes en types de liste unique, vous pouvez effectuer une seule sélection et la transformer en instruction d'insertion JSON ou MongoDB.

Pour ces exemples, je vais supposer que vous voulez le format équivalent à un document pour chaque ville:

{
      State:"Orissa",
      City:{
           Name:"Phulbani",
           Area:[
                 "Phulbani","Phulbani2","Pokali","Madira"
                ]
           }
}

Exemples de données dans SGBDR:

asya=# select * from states;
 id |     name      
----+---------------
  1 | California
  2 | New York
  3 | Massachusetts
(3 rows)

asya=# select * from cities;
 id |     name      | states_id 
----+---------------+-----------
  1 | Los Angeles   |         1
  2 | San Francisco |         1
  3 | San Diego     |         1
  4 | New York      |         2
  5 | Brooklyn      |         2
  6 | Buffalo       |         2
  7 | Boston        |         3
(7 rows)

asya=# select * from cityarea;
 id |        name        | city_id 
----+--------------------+---------
  1 | Beacon Hill        |       7
  2 | Backbay            |       7
  3 | Brookline          |       7
  4 | Park Slope         |       5
  5 | Little Italy       |       4
  6 | SOHO               |       4
  7 | Harlem             |       4
  8 | West Village       |       4
  9 | SoMa               |       2
 10 | South Beach        |       2
 11 | Haight Ashbury     |       2
 12 | Cole Valley        |       2
 13 | Bunker Hill        |       1
 14 | Skid Row           |       1
 15 | Fashion District   |       1
 16 | Financial District |       1
(16 rows)

La manière simple avec les tableaux:

SELECT 'db.cities.insert({ state:"' || states.name || '", city: { name: "' || cities.name || '", areas : [ ' || array_to_string(array_agg('"' || cityarea.name || '"'),',') || ']}});'
FROM states JOIN cities ON (states.id=cities.states_id) LEFT OUTER JOIN cityarea ON (cities.id=cityarea.city_id) GROUP BY states.name, cities.name;

vous donne une sortie qui peut aller directement dans MongoDB Shell:

 db.cities.insert({ state:"California", city: { name: "Los Angeles", areas : [ "Financial District","Fashion District","Skid Row","Bunker Hill"]}});
 db.cities.insert({ state:"California", city: { name: "San Diego", areas : [ ]}});
 db.cities.insert({ state:"California", city: { name: "San Francisco", areas : [ "Haight Ashbury","South Beach","SoMa","Cole Valley"]}});
 db.cities.insert({ state:"Massachusetts", city: { name: "Boston", areas : [ "Beacon Hill","Brookline","Backbay"]}});
 db.cities.insert({ state:"New York", city: { name: "Brooklyn", areas : [ "Park Slope"]}});
 db.cities.insert({ state:"New York", city: { name: "Buffalo", areas : [ ]}});
 db.cities.insert({ state:"New York", city: { name: "New York", areas : [ "Little Italy","West Village","Harlem","SOHO"]}});

Si vous ne prenez pas en charge les types de tableau ou de liste, la méthode la plus longue consiste à sélectionner les données jointes:

asya=# SELECT states.name as state, cities.name as city, cityarea.name as area 
FROM states JOIN cities ON (states.id=cities.states_id) 
LEFT OUTER JOIN cityarea ON (cities.id=cityarea.city_id);
     state     |     city      |        area        
---------------+---------------+--------------------
 California    | Los Angeles   | Financial District
 California    | Los Angeles   | Fashion District
 California    | Los Angeles   | Skid Row
 California    | Los Angeles   | Bunker Hill
 California    | San Francisco | Cole Valley
 California    | San Francisco | Haight Ashbury
 California    | San Francisco | South Beach
 California    | San Francisco | SoMa
 California    | San Diego     | 
 New York      | New York      | West Village
 New York      | New York      | Harlem
 New York      | New York      | SOHO
 New York      | New York      | Little Italy
 New York      | Brooklyn      | Park Slope
 New York      | Buffalo       | 
 Massachusetts | Boston        | Brookline
 Massachusetts | Boston        | Backbay
 Massachusetts | Boston        | Beacon Hill
(18 rows)

J'ai utilisé une jointure externe gauche sur cityarea parce que dans mes données d'échantillon, j'avais une ville sans zones répertoriées mais je voulais obtenir tous les états, paires de villes même s'il n'y avait pas de zone répertoriée pour cela.

Vous pouvez vider cela de manière interactive ou via une ligne de commande (utilisez la syntaxe appropriée pour votre SGBDR). Je vais le faire de manière interactive:

asya=# \a
Output format is unaligned.
asya=# \f
Field separator is "|".
asya=# \f ,
Field separator is ",".
asya=# \t
Showing only tuples.
asya=# \o dump.txt                                                                                                                              
asya=# SELECT states.name as state, cities.name as city, cityarea.name as area 
FROM states JOIN cities ON (states.id=cities.states_id) 
LEFT OUTER JOIN cityarea ON (cities.id=cityarea.city_id);
asya=# \q

J'ai maintenant un fichier séparé par des virgules avec l'état, la ville et la zone comme trois champs. Je peux le charger dans MongoDB via l'utilitaire mongoimport:

asya$ mongoimport -d sample -c tmpcities --type csv --fields state,city,area < dump.txt 
connected to: 127.0.0.1
2014-08-05T07:41:36.744-0700 check 9 18
2014-08-05T07:41:36.744-0700 imported 18 objects

Maintenant, pour transformer au format que je veux, j'utilise l'agrégation:

mongo sample
MongoDB Shell version: 2.6.4
connecting to: sample1
> db.tmpcities.aggregate(
{$group:{_id:"$city", state:{$first:"$state"}, areas:{$Push:"$area"}}},
{$project:{state:1,_id:0,city:{name:"$_id", areas:"$areas"}}},
{$out:'cities'})
> db.cities.find({},{_id:0})
{ "_id" : "Boston", "state" : "Massachusetts", "areas" : [ "Brookline", "Backbay", "Beacon Hill" ] }
{ "_id" : "New York", "state" : "New York", "areas" : [ "West Village", "Harlem", "SOHO", "Little Italy" ] }
{ "_id" : "Buffalo", "state" : "New York", "areas" : [ "" ] }
{ "_id" : "Brooklyn", "state" : "New York", "areas" : [ "Park Slope" ] }
{ "_id" : "San Diego", "state" : "California", "areas" : [ "" ] }
{ "_id" : "San Francisco", "state" : "California", "areas" : [ "Cole Valley", "Haight Ashbury", "South Beach", "SoMa" ] }
{ "_id" : "Los Angeles", "state" : "California", "areas" : [ "Financial District", "Fashion District", "Skid Row", "Bunker Hill" ] }
16
Asya Kamsky

Essayez Mongify . Il prend en charge toutes les contraintes de clé étrangère et d'intégrité référentielle qui existent dans SQL lors de la migration des données dans MongoDB.
Selon sa documentation:

Mongify vous aide à déplacer vos données sans vous soucier des ID ou des ID étrangers. Il vous permet d'incorporer des données dans des documents, y compris des associations polymorphes.

J'espère que ça aide.

3
Ankur Choudhary