Chuyển hướng đầu ra của truy vấn mongo thành tệp csv


85

Tôi đang sử dụng MongoDB 2.2.2 cho máy Windows7 32-bit. Tôi có một truy vấn tổng hợp phức tạp trong tệp .js. Tôi cần thực thi tệp này trên trình bao và hướng đầu ra tới tệp CSV. Tôi đảm bảo rằng truy vấn trả về json "phẳng" (không có khóa lồng nhau), vì vậy nó vốn có thể chuyển đổi thành csv gọn gàng.

Tôi biết về load()eval(). eval()yêu cầu tôi dán toàn bộ truy vấn vào trình bao và chỉ cho phép printjson()bên trong tập lệnh, trong khi tôi cần csv. Và, cách thứ hai: load().. Nó in kết quả đầu ra trên màn hình và một lần nữa ở định dạng json.

Có cách nào Mongo có thể thực hiện chuyển đổi này từ json sang csv không? (Tôi cần tệp csv để chuẩn bị các biểu đồ trên dữ liệu). Tôi đang nghĩ:

1. Mongo có một lệnh tích hợp cho việc này mà tôi không thể tìm thấy ngay bây giờ.
2. Mongo không thể làm điều đó cho tôi; Tôi có thể gửi tối đa đầu ra json tới một tệp mà sau đó tôi cần tự chuyển đổi sang csv.
3. Mongo có thể gửi đầu ra json đến một bộ sưu tập tạm thời, nội dung của chúng có thể dễ dàng mongoexportedsang định dạng csv. Nhưng tôi nghĩ rằng chỉ có các truy vấn giảm bản đồ mới hỗ trợ các tập hợp đầu ra. Có đúng không? Tôi cần nó cho một truy vấn tổng hợp.

Cảm ơn vì bất kì sự giúp đỡ :)


1
Nếu đây là việc bạn làm thường xuyên, bạn có thể cân nhắc viết EXE độc lập bằng .NET, python hoặc bạn có thể sử dụng NodeJs; mỗi cái đều có một trình điều khiển gốc giúp dễ dàng thực thi mã của bạn và tạo ra kết quả mong muốn.
WiredPrairie

Tôi đang tham khảo câu trả lời của Zachary trên stackoverflow.com/questions/4130849/… và có thể chuyển đổi từ json sang csv. Nhưng để thay thế, tôi có thể xuất json vào một bộ sưu tập và sau đó thực hiện một mongoexport không?
Aafreen Sheikh

Tôi khuyên bạn chỉ nên xây dựng một bộ khai thác nhỏ bằng cách sử dụng Node và trình điều khiển MongoDB cho NodeJS và sau đó bạn có thể thực thi bất kỳ mã nào bạn muốn. Bạn sẽ nhận được kết quả bạn muốn rất nhanh chóng mà không cần đến trình bao. Nó sẽ rất dễ bảo trì (và có thể gỡ lỗi).
WiredPrairie

Câu trả lời:


175

Tôi biết câu hỏi này đã cũ nhưng tôi đã dành một giờ để cố gắng xuất một truy vấn phức tạp sang csv và tôi muốn chia sẻ suy nghĩ của mình. Đầu tiên, tôi không thể làm cho bất kỳ bộ chuyển đổi json sang csv nào hoạt động (mặc dù bộ chuyển đổi này trông có vẻ hứa hẹn). Những gì tôi cuối cùng đã làm là ghi tệp csv theo cách thủ công trong tập lệnh mongo của tôi.

Đây là một phiên bản đơn giản nhưng về cơ bản những gì tôi đã làm:

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

Cái này tôi vừa đưa truy vấn vào stdout

mongo test export.js > out.csv

đâu testlà tên của cơ sở dữ liệu tôi sử dụng.


Làm cách nào để xác định db mà Bộ sưu tập người dùng nằm trong?
Nelu

2
@NeluMalancea xem tài liệu MongoDB mà họ có thông tin này. Bạn có thể chỉ định DB bằng cách thêm use <database>vào đầu tập lệnh
GEverding

2
Trên thực tế, vì các trình trợ giúp trình bao như "use <database>" không phải là javascript, chúng không được phép. Xem docs.mongodb.org/manual/tutorial/… . Thay vào đó, hãy bắt đầu tập lệnh của bạn như sau: conn = new Mongo (); db = conn.getDB ('your_db_name');
Steve Hansen Smythe

2
@NeluMalancea lệnh Mongo chấp nhận một url db (và người dùng, vượt qua, ...)
iwein

3
@NeluMalancea testtrong lệnh cuối cùng tên của cơ sở dữ liệu, chỉ cần thay thế nó bằng tên cơ sở dữ liệu của bạn.
Zoltán

112

Tính năng xuất tích hợp của Mongo đang hoạt động tốt, trừ khi bạn muốn thao tác dữ liệu như ngày định dạng, kiểu dữ liệu bí mật, v.v.

Lệnh sau hoạt động như một sự quyến rũ.

    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
Cảm ơn rất nhiều! Gợi ý: bây giờ nó là --type=csvthay vì --csv.
Jan

Hạn chế của mongoexport là bạn không thể thao tác các trường. Id mongo xuất dưới dạng ObjectId (mongidstring). Có thể xuất kết quả từ tập lệnh shell mongo sẽ tốt hơn nếu ai đó muốn thao tác dữ liệu của các trường (ví dụ: ObjectId (mongidstring) .toString ()).
Raj006

tôi có thể thực hiện các phép toán tổng hợp không?
Hendy Irawan

Giải pháp này đã hoạt động. Nhưng đối với Windows, tôi phải thực hiện hai sửa đổi: Tôi chỉ cần dấu nháy đơn kép từ bên ngoài và dấu nháy đơn bên trong như sau -q "{name: 'stackoverflow'}", đối với cổng chỉ định -p lệnh không hoạt động, tôi đã sử dụng - -port
27000.

10

Mở rộng các câu trả lời khác:

Tôi thấy câu trả lời của @ GEverding linh hoạt nhất. Nó cũng hoạt động với tập hợp:

test_db.js

print("name,email");

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

Thực hiện lệnh sau để xuất kết quả:

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

Thật không may, nó thêm văn bản bổ sung vào tệp CSV yêu cầu xử lý tệp trước khi chúng tôi có thể sử dụng:

MongoDB shell version: 3.2.10 
connecting to: test_db

Nhưng chúng tôi có thể làm cho vỏ mongo ngừng phun ra những nhận xét đó và chỉ in những gì chúng tôi đã yêu cầu bằng cách chuyển --quietcờ

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

1
Chỉnh sửa câu trả lời của anh ấy sẽ tốt hơn là thêm một câu mới.
Renato Trở lại

6

Đây là những gì bạn có thể thử:

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

}

Lưu nó vào một tệp, nói "export.js". Chạy lệnh sau:

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

5

Hãy xem cái này

để gửi đi từ trình bao mongo sang tệp. Không có hỗ trợ cho việc gửi đi csv từ trình bao mongos. Bạn sẽ phải tự viết javascript hoặc sử dụng một trong nhiều trình chuyển đổi có sẵn. Google "chuyển đổi json sang csv" chẳng hạn.


0

Chỉ cần cân nhắc ở đây với một giải pháp tốt đẹp mà tôi đã và đang sử dụng. Điều này tương tự như giải pháp của Lucky Soni ở trên, nó hỗ trợ tổng hợp, nhưng không yêu cầu mã hóa cứng tên trường.

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

Lưu nó thành một .jstệp, trong trường hợp này, chúng tôi sẽ gọi nó example.jsvà chạy nó bằng dòng lệnh mongo như sau:

mongo <database_name> example.js --quiet > example.csv
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.