105 votes

Rediriger la sortie d'une requête mongo vers un fichier csv

J'utilise MongoDB 2.2.2 sur une machine Windows7 32 bits. J'ai une requête d'agrégation complexe dans un fichier .js. Je dois exécuter ce fichier sur le shell et diriger la sortie vers un fichier CSV. Je m'assure que la requête renvoie un json "plat" (pas de clés imbriquées), de sorte qu'il est intrinsèquement convertible en un csv soigné.

Je suis au courant load() y eval() . eval() m'oblige à coller la requête entière dans le shell et ne permet qu'à printjson() à l'intérieur du script, alors que j'ai besoin de csv. Et, la deuxième façon : load() Il imprime la sortie à l'écran, et à nouveau au format json.

Existe-t-il un moyen pour Mongo d'effectuer cette conversion de json en csv (j'ai besoin du fichier csv pour préparer des graphiques sur les données). Je pense :

1. Soit Mongo a une commande intégrée pour cela que je n'arrive pas à trouver pour le moment.
2. Mongo ne peut pas le faire pour moi ; je peux tout au plus envoyer la sortie json vers un fichier que je dois ensuite convertir moi-même en csv.
3. Mongo peut envoyer la sortie json vers une collection temporaire, dont le contenu peut être facilement mongoexported au format csv. Mais je pense que seules les requêtes map-reduce prennent en charge les collections de sortie. Est-ce exact ? J'en ai besoin pour une requête d'agrégation.

Merci pour toute aide :)

1voto

TimmyGee Points 193

J'apporte juste une solution intéressante que j'ai utilisée. Elle est similaire à La solution de Lucky Soni ci-dessus en ce sens qu'il prend en charge l'agrégation, mais ne nécessite pas le codage en dur des noms de champs.

cursor = db.<collection_name>.<my_query_with_aggregation>;

headerPrinted = false;
while (cursor.hasNext()) {
    item = cursor.next();

    if (!headerPrinted) {
        print(Object.keys(item).join(','));
        headerPrinted = true;
    }

    line = Object
        .keys(item)
        .map(function(prop) {
            return '"' + item[prop] + '"';
        })
        .join(',');
    print(line);
}

Sauvegardez ceci comme un .js dans ce cas, nous l'appellerons example.js et l'exécuter avec la ligne de commande mongo comme ceci :

mongo <database_name> example.js --quiet > example.csv

0voto

Fidel Points 844

J'utilise la technique suivante. Elle permet de garder facilement les noms de colonnes en phase avec le contenu :

var cursor = db.getCollection('Employees.Details').find({})

var header = []
var rows = []

var firstRow = true
cursor.forEach((doc) => 
{
    var cells = []

    if (firstRow) header.push("employee_number")
    cells.push(doc.EmpNum.valueOf())

    if (firstRow) header.push("name")
    cells.push(doc.FullName.valueOf())    

    if (firstRow) header.push("dob")
    cells.push(doc.DateOfBirth.valueOf())   

    row = cells.join(',')
    rows.push(row)    

    firstRow =  false
})

print(header.join(','))
print(rows.join('\n'))

0voto

Simon Katanski Points 306

Lors de l'exécution d'un script dans un serveur distant. Mongo ajoutera sa propre sortie de journalisation, que nous pourrions vouloir omettre dans notre fichier. --quiet ne désactivera que les journaux liés à la connexion. Pas tous les journaux de Mongo. Dans ce cas, nous devrons peut-être filtrer manuellement les lignes inutiles. Un exemple basé sur Windows :

mongo dbname --username userName --password password --host replicaset/ip:port --quiet printDataToCsv.js | findstr /v "NETWORK" > data.csv

Cela va canaliser la sortie de script et utiliser findstr pour filtrer toutes les lignes qui contiennent la chaîne NETWORK. Plus d'informations sur findstr : https://docs.microsoft.com/en-us/Windows-server/administration/Windows-commands/findstr

Une version Linux de ceci utiliserait grep .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X