Reindirizza l'output della query mongo a un file csv


88

Sto usando MongoDB 2.2.2 per macchine Windows7 a 32 bit. Ho una query di aggregazione complessa in un file .js. Devo eseguire questo file sulla shell e indirizzare l'output a un file CSV. Mi assicuro che la query restituisca un json "piatto" (senza chiavi annidate), quindi è intrinsecamente convertibile in un csv pulito.

Conosco load()e eval(). eval()mi richiede di incollare l'intera query nella shell e consente solo printjson()all'interno dello script, mentre ho bisogno di csv. E il secondo modo: load()..Stampa l'output sullo schermo e di nuovo in formato json.

C'è un modo in cui Mongo può eseguire questa conversione da json a csv? (Ho bisogno di un file csv per preparare i grafici sui dati). Sto pensando:

1. O mongo ha un comando integrato per questo che non riesco a trovare in questo momento.
2. Mongo non può farlo per me; Posso al massimo inviare l'output json a un file che poi devo convertire in csv da solo.
3. Mongo può inviare l'output json a una raccolta temporanea, il cui contenuto può essere facilmente mongoexportedin formato csv. Ma penso che solo le query di riduzione della mappa supportino le raccolte di output. È giusto? Ne ho bisogno per una query di aggregazione.

Grazie per qualsiasi aiuto :)


1
Se questo è qualcosa che fai frequentemente, potresti prendere in considerazione la possibilità di scrivere un EXE autonomo utilizzando .NET, python, oppure potresti usare NodeJs; ognuno ha un driver nativo che semplifica l'esecuzione del codice e produce l'output desiderato.
WiredPrairie

Mi riferisco alla risposta di Zachary su stackoverflow.com/questions/4130849/… e sono in grado di convertire da json a csv. Ma in alternativa, posso inviare in output il json a una raccolta e quindi eseguire un mongoexport?
Aafreen Sheikh

Ti consiglio di creare un piccolo cablaggio utilizzando Node e il driver MongoDB per NodeJS e quindi puoi eseguire qualsiasi codice desideri. Otterresti i risultati desiderati molto rapidamente senza bisogno della shell. Sarebbe molto gestibile (e debuggabile).
WiredPrairie

Risposte:


179

So che questa domanda è vecchia ma passo un'ora cercando di esportare una query complessa in csv e volevo condividere i miei pensieri. Innanzitutto non sono riuscito a far funzionare nessuno dei convertitori da json a csv (anche se questo sembrava promettente). Quello che ho finito per fare è stato scrivere manualmente il file csv nel mio script mongo.

Questa è una versione semplice ma essenzialmente quello che ho fatto:

print("name,id,email");
db.User.find().forEach(function(user){
  print(user.name+","+user._id.valueOf()+","+user.email);
});

Questo ho appena inviato la query a stdout

mongo test export.js > out.csv

dov'è testil nome del database che utilizzo.


Come posso specificare in quale db si trova la raccolta utente?
Nelu

2
@NeluMalancea controlla i documenti di MongoDB che hanno queste informazioni. È possibile specificare il DB aggiungendo use <database>all'inizio dello script
GEverding

2
In realtà, poiché gli helper della shell come "use <database>" non sono javascript, non sono consentiti. Vedere docs.mongodb.org/manual/tutorial/… . Invece, avvia lo script in questo modo: conn = new Mongo (); db = conn.getDB ('your_db_name');
Steve Hansen Smythe

2
@NeluMalancea il comando mongo accetta un URL db (e utente, passaggio, ...)
iwein

3
@NeluMalancea l' testultimo comando è il nome del database, basta sostituirlo con il nome del tuo database.
Zoltán

116

L'esportazione incorporata di Mongo funziona bene, a meno che tu non voglia manipolare i dati come formattare la data, tipi di dati nascosti ecc.

Seguire il comando funziona come un fascino.

    mongoexport -h localhost -d databse -c collection --type=csv 
    --fields erpNum,orderId,time,status 
    -q '{"time":{"$gt":1438275600000}, "status":{"$ne" :"Cancelled"}}' 
    --out report.csv

17
Grazie mille! Suggerimento: ora è --type=csvinvece di --csv.
gennaio

La limitazione di mongoexport è che non puoi manipolare i campi. L'id mongo esporta come ObjectId (mongidstring). Essere in grado di esportare i risultati da uno script di shell mongo è meglio se qualcuno vuole manipolare i dati dei campi (ad esempio ObjectId (mongidstring) .toString ()).
Raj006

1
posso fare operazioni di aggregazione?
Hendy Irawan

Questa soluzione ha funzionato. Ma per Windows ho dovuto fare due modifiche: avevo solo bisogno di un doppio apostrofo dall'esterno e di singoli apostrofi all'interno come questo -q "{name: 'stackoverflow'}", anche per la porta specificando il comando -p non funzionava, ho usato - -port 27000.
nurb

10

Estendendo altre risposte:

Ho trovato la risposta di @ GEverding più flessibile. Funziona anche con l'aggregazione:

test_db.js

print("name,email");

db.users.aggregate([
    { $match: {} }
]).forEach(function(user) {
        print(user.name+","+user.email);
    }
});

Esegui il seguente comando per esportare i risultati:

mongo test_db < ./test_db.js >> ./test_db.csv

Sfortunatamente, aggiunge testo aggiuntivo al file CSV che richiede l'elaborazione del file prima di poterlo utilizzare:

MongoDB shell version: 3.2.10 
connecting to: test_db

Ma possiamo fare in modo che mongo shell smetta di sputare quei commenti e stampi solo ciò che abbiamo chiesto passando la --quietbandiera

mongo --quiet test_db < ./test_db.js >> ./test_db.csv

1
Modificare la sua risposta sarebbe meglio che aggiungerne una nuova.
Renato Back

6

Ecco cosa puoi provare:

print("id,name,startDate")
cursor = db.<collection_name>.find();
while (cursor.hasNext()) {
    jsonObject = cursor.next();
    print(jsonObject._id.valueOf() + "," + jsonObject.name + ",\"" + jsonObject.stateDate.toUTCString() +"\"")

}

Salvalo in un file, dì "export.js". Esegui il seguente comando:

mongo <host>/<dbname> -u <username> -p <password> export.js > out.csv

5

Dai un'occhiata a questo

per l'output da mongo shell a file. Non c'è supporto per l'output di csv dalla shell mongos. Dovresti scrivere tu stesso il javascript o usare uno dei tanti convertitori disponibili. Google "converte json in csv" per esempio.


1

Sto solo soppesando qui con una bella soluzione che ho usato. Questo è simile alla soluzione di Lucky Soni sopra in quanto supporta l'aggregazione, ma non richiede l'hard coding dei nomi dei campi.

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);
}

Salvalo come .jsfile, in questo caso lo chiameremo example.jse lo eseguiremo con la riga di comando di mongo in questo modo:

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

0

Uso la seguente tecnica. Semplifica la sincronizzazione dei nomi delle colonne con il contenuto:

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'))

0

Quando si esegue uno script in un server remoto. Mongo aggiungerà il proprio output di registrazione, che potremmo voler omettere dal nostro file. --quietL'opzione disabiliterà solo i log relativi alla connessione. Non tutti i registri di mongo. In tal caso, potrebbe essere necessario filtrare manualmente le righe non necessarie. Un esempio basato su Windows:

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

Ciò reindirizzerà l'output dello script e utilizzerà findstrper filtrare tutte le righe che contengono una stringa NETWORK. Ulteriori informazioni su findstr: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr

Una versione Linux di questo userebbe grep.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.