Leiten Sie die Ausgabe der Mongo-Abfrage in eine CSV-Datei um

85

Ich verwende MongoDB 2.2.2 für 32-Bit-Windows7-Computer. Ich habe eine komplexe Aggregationsabfrage in einer .js-Datei. Ich muss diese Datei auf der Shell ausführen und die Ausgabe in eine CSV-Datei leiten. Ich stelle sicher, dass die Abfrage einen "flachen" JSON (keine verschachtelten Schlüssel) zurückgibt, sodass sie von Natur aus in eine ordentliche CSV konvertiert werden kann.

Ich weiß über load()und eval(). eval()erfordert, dass ich die gesamte Abfrage in die Shell einfüge und nur printjson()innerhalb des Skripts zulasse, während ich csv benötige. Und der zweite Weg: load()..Es druckt die Ausgabe auf dem Bildschirm und wieder im JSON-Format.

Gibt es eine Möglichkeit, wie Mongo diese Konvertierung von json nach csv durchführen kann? (Ich benötige eine CSV-Datei, um Diagramme für die Daten vorzubereiten). Ich denke:

1. Entweder hat Mongo einen eingebauten Befehl dafür, den ich momentan nicht finden kann.
2. Mongo kann es nicht für mich tun; Ich kann die JSON-Ausgabe höchstens an eine Datei senden, die ich dann selbst in CSV konvertieren muss.
3. Mongo kann die JSON-Ausgabe an eine temporäre Sammlung senden, deren Inhalt leicht mongoexportedim CSV-Format vorliegen kann. Ich denke jedoch, dass nur kartenreduzierte Abfragen Ausgabesammlungen unterstützen. Ist das richtig? Ich brauche es für eine Aggregationsabfrage.

Danke für jede Hilfe :)

Aafreen Sheikh
quelle
1
Wenn Sie dies häufig tun, können Sie eine eigenständige EXE-Datei mit .NET, Python oder NodeJs schreiben. Jeder hat einen nativen Treiber, der es einfach macht, Ihren Code auszuführen und die gewünschte Ausgabe zu erzeugen.
WiredPrairie
Ich beziehe mich auf Zacharys Antwort auf stackoverflow.com/questions/4130849/… und kann von json nach csv konvertieren. Aber kann ich alternativ den JSON in eine Sammlung ausgeben und dann einen Mongoexport durchführen?
Aafreen Sheikh
Ich würde empfehlen, dass Sie nur ein kleines Kabel mit Node und dem MongoDB-Treiber für NodeJS erstellen und dann den gewünschten Code ausführen können. Sie würden die gewünschten Ergebnisse sehr schnell erhalten, ohne die Shell überhaupt zu benötigen. Es wäre sehr wartbar (und debuggbar).
WiredPrairie

Antworten:

175

Ich weiß, dass diese Frage alt ist, aber ich verbringe eine Stunde damit, eine komplexe Abfrage nach CSV zu exportieren, und wollte meine Gedanken teilen. Zuerst konnte ich keinen der JSON-CSV-Konverter zum Laufen bringen (obwohl dieser vielversprechend aussah). Am Ende habe ich die CSV-Datei manuell in mein Mongo-Skript geschrieben.

Dies ist eine einfache Version, aber im Wesentlichen das, was ich getan habe:

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

Dies habe ich gerade die Abfrage an stdout weitergeleitet

mongo test export.js > out.csv

Wo testist der Name der Datenbank, die ich benutze?

GEverding
quelle
Wie würde ich angeben, in welcher Datenbank sich die Benutzersammlung befindet?
Nelu
2
@NeluMalancea Überprüfen Sie die MongoDB- Dokumente , in denen diese Informationen enthalten sind. Sie können die use <database>
Datenbank
2
Da die Shell-Helfer wie "use <database>" kein Javascript sind, sind sie nicht zulässig. Siehe docs.mongodb.org/manual/tutorial/… . Starten Sie stattdessen Ihr Skript wie folgt: conn = new Mongo (); db = conn.getDB ('your_db_name');
Steve Hansen Smythe
2
@NeluMalancea Der Mongo-Befehl akzeptiert eine Datenbank-URL (und Benutzer, Pass, ...)
iwein
3
@NeluMalancea Der testim letzten Befehl angegebene Name ist der Name der Datenbank. Ersetzen Sie ihn einfach durch den Namen Ihrer Datenbank.
Zoltán
112

Der integrierte Export von Mongo funktioniert einwandfrei, es sei denn, Sie möchten Datenmanipulationen wie Formatdatum, verdeckte Datentypen usw. vornehmen.

Der folgende Befehl wirkt als Zauber.

    mongoexport -h localhost -d databse -c collection --type=csv 
    --fields erpNum,orderId,time,status 
    -q '{"time":{"$gt":1438275600000}, "status":{"$ne" :"Cancelled"}}' 
    --out report.csv
thisarattr
quelle
17
Danke vielmals! Hinweis: Jetzt ist es --type=csvstatt --csv.
Januar
Die Einschränkung des Mongoexports besteht darin, dass Sie die Felder nicht bearbeiten können. Die Mongo-ID wird als ObjectId (Mongidstring) exportiert. Das Exportieren der Ergebnisse aus einem Mongo-Shell-Skript ist besser, wenn jemand die Daten der Felder bearbeiten möchte (z. B. ObjectId (mongidstring) .toString ()).
Raj006
Kann ich Aggregationsoperationen durchführen?
Hendy Irawan
Diese Lösung hat funktioniert. Aber für Windows musste ich zwei Änderungen vornehmen: Ich brauchte nur einen doppelten Apostroph von außen und einen einzelnen Apostroph von innen wie diesen -q "{name: 'stackoverflow'}", auch für den Port, der den Befehl -p spezifizierte, funktionierte nicht - ich benutzte - -port 27000.
nurb
10

Weitere Antworten erweitern:

Ich fand die Antwort von @ GEverding am flexibelsten. Es funktioniert auch mit Aggregation:

test_db.js

print("name,email");

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

Führen Sie den folgenden Befehl aus, um die Ergebnisse zu exportieren:

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

Leider wird der CSV-Datei zusätzlicher Text hinzugefügt, für den die Datei verarbeitet werden muss, bevor wir sie verwenden können:

MongoDB shell version: 3.2.10 
connecting to: test_db

Aber wir können dafür sorgen, dass die Mongo-Shell diese Kommentare nicht mehr ausspuckt und nur das druckt, wonach wir gefragt haben, indem wir die --quietFlagge übergeben

mongo --quiet test_db < ./test_db.js >> ./test_db.csv
Glückliche Soni
quelle
1
Das Bearbeiten seiner Antwort wäre besser als das Hinzufügen einer neuen.
Renato Zurück
6

Folgendes können Sie versuchen:

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

}

Speichern Sie das in einer Datei, sagen Sie "export.js". Führen Sie den folgenden Befehl aus:

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

Werfen Sie einen Blick auf diese

für die Ausgabe von Mongo Shell in Datei. Es gibt keine Unterstützung für die Ausgabe von CSV aus der Mongos-Shell. Sie müssten das Javascript selbst schreiben oder einen der vielen verfügbaren Konverter verwenden. Google "konvertiere json in csv" zum Beispiel.

Geakie
quelle
0

Ich wäge hier nur mit einer schönen Lösung ab, die ich verwendet habe. Dies ähnelt der obigen Lösung von Lucky Soni, da es die Aggregation unterstützt, jedoch keine feste Codierung der Feldnamen erfordert.

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

Speichern Sie dies als .jsDatei. In diesem Fall rufen wir es auf example.jsund führen es mit der Mongo-Befehlszeile wie folgt aus:

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