Czy istnieje sposób na „ładne” wydrukowanie danych wyjściowych powłoki MongoDB do pliku?

101

W szczególności chcę wydrukować wyniki mongodb find()do pliku. Obiekt JSON jest zbyt duży, więc nie mogę wyświetlić całego obiektu z rozmiarem okna powłoki.

żmija
źródło

Odpowiedzi:

216

Powłoka zapewnia kilka fajnych, ale ukrytych funkcji, ponieważ jest to środowisko interaktywne.

Gdy uruchamiasz polecenia z pliku javascript za pośrednictwem mongo commands.js, nie uzyskasz identycznego zachowania.

Można to obejść na dwa sposoby.

(1) sfałszuj powłokę i spraw, by myślała, że ​​jesteś w trybie interaktywnym

$ mongo dbname << EOF > output.json
db.collection.find().pretty()
EOF

lub
(2) użyj Javascript do przetłumaczenia wyniku a find()na drukowalny JSON

mongo dbname command.js > output.json

gdzie command.js zawiera to (lub jego odpowiednik):

printjson( db.collection.find().toArray() )

Spowoduje to wyświetlenie tablicy wyników, w tym [ ]- jeśli nie chcesz, możesz iterować po tablicy i printjson()każdym elemencie.

Nawiasem mówiąc, jeśli uruchamiasz tylko jedną instrukcję Javascript, nie musisz umieszczać jej w pliku i zamiast tego możesz użyć:

$ mongo --quiet dbname --eval 'printjson(db.collection.find().toArray())' > output.json
Asya Kamsky
źródło
command.js musi być plikiem możliwym do odczytania, który istnieje w Twoim bieżącym katalogu i zawiera skrypt javascript, który chcesz uruchomić.
Asya Kamsky
Jak to zrobić dla zdalnej bazy danych mongo? Próbowałem, mongo blah.mongolab.com:33478/blah -u user -p pass --eval "my query" >> dump.txtale to mi dało JavaScript execution failed: SyntaxError: Unexpected token ILLEGAL.
Sheharyar,
ten błąd oznacza, że ​​to, co znajduje się w cudzysłowie po --eval, nie jest legalną składnią. Zalecam używanie pojedynczych cudzysłowów poza całymi wyrażeniami, a jeśli potrzebujesz w nim cudzysłowów, użyj do tego podwójnych cudzysłowów.
Asya Kamsky,
2
Opcja 2 jest naprawdę jedyną opcją, jeśli masz więcej niż garść wyników, ponieważ w opcji 1 zatrzyma się po prostu na „Wpisz„ to ”, aby uzyskać więcej”.
Tomty
2
nie bardzo @Tomty - rozmiar wsadu powłoki jest kontrolowany za pomocą zmiennej wewnątrz powłoki. możesz umieścić DBQuery.shellBatchSize = 10000 w swoim pliku .mongodbrc.js i zatrzyma się on po 10000 wyników zamiast 20.
Asya Kamsky
29

Ponieważ robisz to na terminalu i chcesz po prostu sprawdzić rekord w rozsądny sposób, możesz użyć takiej sztuczki:

mongo | tee somefile

Używaj sesji w normalny sposób - db.collection.find().pretty()lub cokolwiek musisz zrobić, zignoruj ​​długie dane wyjściowe i zakończ. Zapis Twojej sesji będzie znajdował się w pliku, teedo którego została zapisana .

Należy pamiętać, że dane wyjściowe mogą zawierać sekwencje ucieczki i inne śmieci, ponieważ powłoka mongo oczekuje sesji interaktywnej. lessradzi sobie z nimi wdzięcznie.

Falcon Momot
źródło
12

Po prostu umieść polecenia, które chcesz uruchomić w pliku, a następnie przekaż je do powłoki wraz z nazwą bazy danych i przekieruj dane wyjściowe do pliku. Tak więc, jeśli polecenie find znajduje się, find.jsa baza danych jest foo, wyglądałoby to tak:

./mongo foo find.js >> out.json
Adam Comerford
źródło
To nie zadziałało dla mnie, tylko wydrukowano wersję powłoki i nazwę bazy danych do out.json. mongo foo < find.js > out.jsonzadziałało.
James Brown,
1
ta odpowiedź została napisana zanim narzędzia zostały przepisane w Go i wiele wersji temu, chyba że używasz czegoś bardzo starego, to prawdopodobnie dlatego nie działa dla Ciebie
Adam Comerford
10

Umieść zapytanie (np. db.someCollection.find().pretty()) W pliku javascript, powiedzmy query.js. Następnie uruchom go w powłoce swojego systemu operacyjnego za pomocą polecenia:

mongo yourDb < query.js > outputFile

Wynik zapytania będzie w pliku o nazwie „outputFile”.

Domyślnie Mongo drukuje pierwsze 20 dokumentów IIRC. Jeśli chcesz więcej, możesz zdefiniować nową wartość rozmiaru partii w powłoce Mongo, np

DBQuery.shellBatchSize = 100.

John P.
źródło
To. Nie daj się zwieść przez .jsrozszerzenie. Możesz pisać wszystkie te ładne zapytania do powłoki mongo bez ich zmiany.
AD
4

Używając printi JSON.stringifymożesz po prostu wygenerować ważny JSON wynik.
Użyj --quietflagi, aby odfiltrować szum powłoki z wyjścia.
Użyj --norcflagi, aby uniknąć .mongorc.jsoceny. (Musiałem to zrobić ze względu na ładny program formatujący, którego używam, który generuje nieprawidłowe dane wyjściowe JSON ). Użyj DBQuery.shellBatchSize = ?zastępowania ?limitem rzeczywistego wyniku, aby uniknąć stronicowania.

Na koniec użyj, teeaby przesłać dane wyjściowe terminala do pliku:

// Shell:
mongo --quiet --norc ./query.js | tee ~/my_output.json

// query.js:
DBQuery.shellBatchSize = 2000;
function toPrint(data) {
  print(JSON.stringify(data, null, 2));
}

toPrint(
  db.getCollection('myCollection').find().toArray()
);

Mam nadzieję że to pomoże!

Dmitrij
źródło
2

Korzystając z odpowiedzi Asyi Kamsky'ego, napisałem jednowierszowy skrypt dla systemu Windows. Linia wygląda następująco:

mongo --quiet %1 --eval "printjson(db.%2.find().toArray())" > output.json

Następnie można go uruchomić:

exportToJson.bat DbName CollectionName

margaretkru
źródło
2

Udało mi się zapisać wynik dzięki funkcji writeFile () .

> writeFile("/home/pahan/output.txt", tojson(db.myCollection.find().toArray()))

Wersja powłoki Mongo to 4.0.9

Pavel_H
źródło
1

Jest też do tego mongoeksport , ale nie jestem pewien, od której wersji jest on dostępny.

Przykład:

mongoexport -d dbname -c collection --jsonArray --pretty --quiet --out output.json
Neodan
źródło
0

Jako odpowiedź Neodan mongoexport jest całkiem przydatny z -qopcją zapytania. Konwertuje również ObjectIddo standardowego formatu JSON "$oid". Na przykład:

mongoexport -d yourdb -c yourcol --jsonArray --pretty -q '{"field": "filter value"}' -o output.json
Nhan D Le
źródło
0

możesz użyć tego polecenia, aby to osiągnąć:

mongo admin -u <userName> -p <password> --quiet --eval "cursor = rs.status(); printjson(cursor)" > output.json

Parimal Jana
źródło