2012-12-02 21 views
3

試圖在mongodb中獲取一些數據(〜500Mb)的CSV轉儲。思想流將是要走的路,避免在內存中建立數組,然後立即構建csv。通過貓鼬流輸出到節點csv

但是,似乎貓鼬創造的流和csv期望的流不是同一件事。

var stream = Subscriber.find().stream()                         
stream.setEncoding = function() { }                          


csv().from.stream(stream).on('record', function(record, index) {                   
    console.log(record)                             
    console.log(index)                              
}) 

不高於setEncoding()存根,我得到一個錯誤,當CSV流上調用setEncoding。有了它,結果在

TypeError: Object #<Object> has no method 'indexOf' 
    at [object Object].stringify (/home/project/node_modules/csv/lib/stringifier.js:98:35) 

所以,這是甚至正確的方法?如果是這樣,那麼溪流的問題是什麼?

+1

你想在節點做這個嗎?因爲您可以使用[mongoimport](http://docs.mongodb.org/manual/administration/import-export/#collection-import-with-mongoimport)將csv轉儲到mongodb中。 – zemirco

回答

1

正如zeMirco所說:要獲得集合的CSV轉儲,我會使用MongoDB附帶的mongoexport工具。下面是一個數據庫「MyDatabase的」以CSV格式導出一個名爲「用戶」收集的一個例子:

$ mongoexport --csv --host localhost:27017 --db mydatabase --collection users --fields name,email,age -o output.csv 

你會得到的東西看起來是這樣的:

$ cat output.csv 
name,email,age 
renold,[email protected],21 
jacob,[email protected],16 
+0

好主意,但我們需要對每個返回的文檔(即轉換)進行計數,日期分析,聚合等。 AFAIK'mongoexport'不能這樣做 – sbeam

+1

您可以使用'--json'標誌將所有內容導出爲JSON,將其加載到Node中進行處理,然後再以[json2csv](https:// npmjs.org/package/json2csv)。或者你可以通過節點創建一個新的帶有處理文檔的集合,然後導出它。或者,也許你可以使用MapReduce,如果這符合你的處理風格。 – theabraham

+0

「通過節點創建一個處理文檔的新集合」 - 有趣的解決方法,可能會嘗試。實際上問題不是創建一個CSV,我可以用'node-csv'來完成這個工作,它可以處理我們迄今爲止所用的小數據集。但是想知道爲什麼mongoose model'stream()'不能與'csv()。from.stream()'一起工作,因爲流似乎是更大數據的途徑(可能不是這種情況,prob應該無論如何分解csv) – sbeam

0

像這樣的東西應該工作。將process.stdout替換爲文件流以將其寫入文件。

var csv = require('csv') 
var through = require('through') 
var Model = require('...') 
_ = require('underscore') 

var modelStream = Model.find().stream(); 

modelStream.pipe(through(write, end)).pipe(csv()).pipe(process.stdout); 

function end(){ console.log('done'); } 
function write(doc) { 
    this.queue(_.values(doc.toObject({getters:true, virtuals:false}))); 
} 
0

如果你想通過訪問URL和您使用快遞,你可以做到這一點,下載從Web服務器的CSV:

var through = require('through'); 
var csv = require('csv') 
var MyModel = require('./my_model'); 

app.get('/download_csv/', function(req, res) { 

    res.setHeader('Content-disposition', 'attachment; filename=attendances.csv'); 
    res.contentType('csv'); 
    res.write('property 1,property 2\n'); 

    var modelStream = MyModel.find().stream(); 

    modelStream. 
     pipe(through(write, end)). 
     pipe(csv.stringify()). 
     pipe(res); 

    function end() { 
     res.end(); 
     console.log('done outputting file'); 
    } 

    function write(doc) { 
     var myObject = doc.toObject({getters:true, virtuals:false}); 
     this.queue([ 
      myObject.property_1, 
      myObject.property_2 
     ]); 
    } 
}); 

注:這是使用最新版本的CSV模塊( v0.4),而以前的答案是使用模塊的舊版本。