Có cách nào để in đầu ra vỏ MongoDB 'đẹp' ra một tệp không?


101

Cụ thể, tôi muốn in kết quả của mongodb find()vào một tệp. Đối tượng JSON quá lớn nên tôi không thể xem toàn bộ đối tượng với kích thước cửa sổ shell.

Câu trả lời:


216

Vỏ cung cấp một số tính năng hay nhưng ẩn vì đó là một môi trường tương tác.

Khi bạn chạy các lệnh từ tệp javascript qua mongo command.js, bạn sẽ không nhận được hành vi hoàn toàn giống nhau.

Có hai cách để giải quyết vấn đề này.

(1) giả mạo và làm cho nó nghĩ rằng bạn đang ở chế độ tương tác

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

hoặc
(2) sử dụng Javascript để dịch kết quả của a find()thành JSON có thể in được

mongo dbname command.js > output.json

nơi command.js chứa cái này (hoặc tương đương):

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

Điều này sẽ in ra mảng kết quả, bao gồm [ ]- nếu bạn không muốn, bạn có thể lặp qua mảng và printjson()từng phần tử.

Nhân tiện, nếu bạn đang chạy chỉ một câu lệnh Javascript, bạn không phải đặt nó vào một tệp và thay vào đó bạn có thể sử dụng:

$ mongo --quiet dbname --eval 'printjson(db.collection.find().toArray())' > output.json

command.js phải là một tệp có thể đọc được tồn tại trong thư mục hiện tại của bạn và có javascript bạn muốn chạy.
Asya Kamsky

Làm cách nào để làm điều đó cho một db mongo từ xa? Tôi đã cố gắng mongo blah.mongolab.com:33478/blah -u user -p pass --eval "my query" >> dump.txtnhưng nó đã cho tôi JavaScript execution failed: SyntaxError: Unexpected token ILLEGAL.
Sheharyar

lỗi đó có nghĩa là những gì bên trong dấu ngoặc kép của bạn sau --eval không phải là cú pháp hợp pháp. Tôi khuyên bạn nên sử dụng dấu ngoặc kép bên ngoài toàn bộ biểu thức và nếu bạn cần dấu ngoặc kép bên trong nó, hãy sử dụng dấu ngoặc kép cho điều đó.
Asya Kamsky

2
Tùy chọn 2 thực sự là lựa chọn duy nhất nếu bạn có nhiều hơn một số kết quả, vì trong tùy chọn 1, nó sẽ chỉ dừng lại ở 'Nhập "nó" để biết thêm'.
Tomty

2
không thực sự @Tomty - kích thước của lô shell có thể kiểm soát được bằng một biến bên trong shell. bạn có thể đặt DBQuery.shellBatchSize = 10000 vào tập tin .mongodbrc.js của bạn và nó sẽ "dừng" sau 10000 kết quả thay vì 20.
Asya Kamsky

29

Vì bạn đang thực hiện việc này trên một thiết bị đầu cuối và chỉ muốn kiểm tra bản ghi một cách lành mạnh, bạn có thể sử dụng một thủ thuật như sau:

mongo | tee somefile

Sử dụng phiên như bình thường - db.collection.find().pretty()hoặc bất cứ điều gì bạn cần làm, bỏ qua đầu ra dài và thoát. Bản ghi phiên của bạn sẽ có trong tệptee ghi vào.

Hãy lưu ý rằng đầu ra có thể chứa các chuỗi thoát và rác khác do trình bao mongo mong đợi một phiên tương tác. lessxử lý những điều này một cách duyên dáng.


12

Chỉ cần đặt các lệnh bạn muốn chạy vào một tệp, sau đó chuyển nó vào trình bao cùng với tên cơ sở dữ liệu và chuyển hướng đầu ra đến một tệp. Vì vậy, nếu lệnh find của bạn có trong find.jsvà cơ sở dữ liệu của bạn foo, nó sẽ giống như sau:

./mongo foo find.js >> out.json

Điều này không làm việc với tôi, chỉ in ra phiên bản shell và tên db cho out.json. mongo foo < find.js > out.jsonĐã làm việc.
James Brown

1
Câu trả lời này đã được viết trước khi các công cụ được viết lại bằng Go và nhiều phiên bản trước, trừ khi bạn đang sử dụng một cái gì đó rất cũ, sau đó là của lẽ lý do tại sao nó không làm việc cho bạn
Adam Comerford

10

Đặt truy vấn của bạn (ví dụ db.someCollection.find().pretty()) vào một tệp javascript, giả sử query.js. Sau đó chạy nó trong trình bao hệ điều hành của bạn bằng lệnh:

mongo yourDb < query.js > outputFile

Kết quả truy vấn sẽ nằm trong tệp có tên 'outputFile'.

Theo mặc định, Mongo in ra 20 tài liệu IIRC đầu tiên. Nếu bạn muốn nhiều hơn, bạn có thể xác định giá trị mới cho kích thước hàng loạt trong Mongo shell, ví dụ:

DBQuery.shellBatchSize = 100.


Điều này. Đừng bị điều hướng sai bởi .jstiện ích mở rộng. Bạn có thể viết tất cả các truy vấn shell mongo tuyệt vời đó mà không cần thay đổi chúng.
sau Công nguyên

4

Sử dụng printJSON.stringifybạn có thể chỉ cần tạo ra một kết quả hợp lệ JSON .
Sử dụng --quietcờ để lọc nhiễu shell từ đầu ra.
Sử dụng --norccờ để tránh .mongorc.jsđánh giá. (Tôi phải làm điều đó vì một định dạng đẹp mà tôi sử dụng, tạo ra đầu ra JSON không hợp lệ ) Sử dụng DBQuery.shellBatchSize = ?thay thế? bằng giới hạn của kết quả thực tế để tránh phân trang.

Và cuối cùng, sử dụng teeđể chuyển đầu ra của thiết bị đầu cuối thành một tệp:

// 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()
);

Hi vọng điêu nay co ich!


2

Sử dụng câu trả lời này từ Asya Kamsky, tôi đã viết một tập lệnh con dơi một dòng cho Windows. Dòng trông như thế này:

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

Sau đó, người ta có thể chạy nó:

exportToJson.bat DbName CollectionName


2

Tôi đã quản lý để lưu kết quả bằng hàm writeFile () .

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

Phiên bản vỏ Mongo là 4.0.9


1

Ngoài ra còn có mongoexport cho điều đó, nhưng tôi không chắc nó có sẵn phiên bản nào.

Thí dụ:

mongoexport -d dbname -c collection --jsonArray --pretty --quiet --out output.json

0

Như câu trả lời của Neodan mongoexport khá hữu ích với -qtùy chọn cho truy vấn. Nó cũng chuyển đổi ObjectIdsang định dạng tiêu chuẩn của JSON "$oid". Ví dụ:

mongoexport -d yourdb -c yourcol --jsonArray --pretty -q '{"field": "filter value"}' -o output.json

0

bạn có thể sử dụng lệnh này để thực hiện nó:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.