2012-03-30 22 views
1

これは簡単に行うべきだと私は知っていますが、今日それを見て数時間を費やしたにもかかわらず、それをどうやって行うのかは分かりません。私が知る限り、オンラインで簡単な例やチュートリアルは表示されません。CouchDBからCSVビューを作成する

私はCouchDBデータベースに複数の「テーブル」があり、各「テーブル」はドキュメントの「スキーマ」フィールドに異なる値を持っています。同じスキーマを持つすべてのドキュメントには、同じフィールドセットが含まれています。私がしたいのは、CSV形式のさまざまな「テーブル」を表示できることだけです。各スキーマのフィールド名のリストを指定する必要はありません。

CSV出力はRスクリプトによって消費されるため、回避することができれば出力に追加のヘッダーは必要ありません。カンマ区切りのCSV形式の値を持つフィールド名のリストだけです。例えば

、 "TABLE1" 形式の2つのレコードは次のようになります。

{  
    "schema": "table1", 
    "field1": 17, 
    "field2": "abc", 
    ... 
    "fieldN": "abc", 
    "timestamp": "2012-03-30T18:00:00Z" 
} 

{ 
    "schema": "table1", 
    "field1": 193, 
    "field2": "xyz", 
    ... 
    "fieldN": "ijk", 
    "timestamp": "2012-03-30T19:01:00Z" 
} 

私の見解は非常に単純です:

"all": "function(doc) { 
    if (doc.schema == "table1") { 
     emit(doc.timestamp, doc) 
    } 
}" 

私が好きな私のレコードをタイムスタンプ順に並べ替える。

おそらくリスト機能は次のようになります:

"csv": "function(head, req) { 
    var row; 
    ... 
    // Something here to iterate through the list of fieldnames and print them 
    // comma separated 
    for (row in getRow) { 
     // Something here to iterate through each row and print the field values 
     // comma separated 
    } 
}" 

が、私はちょうどそれの残りのまわりで私の頭を取得することはできません。

私はCSV出力が

"timestamp", "field1", "field2", ..., "fieldN" 
"2012-03-30T18:00:00Z", 17, "abc", ..., "abc" 
"2012-03-30T19:01:00Z", 193, "xyz", ..., "ijk" 

のように見て取得したい場合はどのような私のCouchDBのリスト機能は次のようになりますか?

ここでは、事前

答えて

1

のおかげでマックス・オグデンが書かれているいくつかの一般的なコード。それは、ノードcouchappの形であるが、おそらくアイデアを得ることができます。

 
var couchapp = require('couchapp') 
    , path = require('path') 
    ; 

ddoc = { _id:'_design/csvexport' }; 

ddoc.views = { 
    headers: { 
    map: function(doc) { 
     var keys = []; 
     for (var key in doc) { 
     emit(key, 1);   
     } 
    }, 
    reduce: "_sum" 
    } 
}; 

ddoc.lists = { 
    /** 
    * Generates a CSV from all the rows in the view. 
    * 
    * Takes in a url encoded array of headers as an argument. You can 
    * generate this by querying /_list/urlencode/headers. Pass it in 
    * as the headers get parameter, e.g.: ?headers=%5B%22_id%22%2C%22_rev%5D 
    * 
    * @author Max Ogden 
    */ 
    csv: function(head, req) { 
    if ('headers' in req.query) { 
     var headers = JSON.parse(unescape(req.query.headers)); 

     var row, sep = '\n', headerSent = false, startedOutput = false; 

     start({"headers":{"Content-Type" : "text/csv; charset=utf-8"}}); 
     send('"' + headers.join('","') + '"\n'); 
     while (row = getRow()) { 
     for (var header in headers) { 
      if (row.value[headers[header]]) { 
      if (startedOutput) send(","); 
      var value = row.value[headers[header]]; 
      if (typeof(value) == "object") value = JSON.stringify(value); 
      if (typeof(value) == "string") value = value.replace(/\"/g, '""'); 
      send("\"" + value + "\""); 
      } else { 
      if (startedOutput) send(","); 
      } 
      startedOutput = true; 
     } 
     startedOutput = false; 
     send('\n'); 
     } 
    } else { 
     send("You must pass in the urlencoded headers you wish to build the CSV from. Query /_list/urlencode/headers?group=true"); 
    } 
    } 
} 

module.exports = ddoc; 

出典:あなたの指定されたマップと連動し https://github.com/kanso/kanso/issues/336

3

リスト機能は、次のようになります。

function(head,req) { 
    var headers; 
    start({'headers':{'Content-Type' : 'text/csv; charset=utf-8; header=present'}}); 
    while(r = getRow()) { 
    if(!headers) { 
     headers = Object.keys(r.value); 
     send('"' + headers.join('","') + '"\n'); 
    } 
    headers.forEach(function(v,i) { 
     send(String(r.value[v]).replace(/\"/g,'""').replace(/^|$/g,'"')); 
     (i + 1 < headers.length) ? send(',') : send('\n'); 
    }); 
    } 
} 

Ryanの提案とは異なり、リストに含めるフィールドはこの関数では設定できません。また、順序やインクルードフィールドの変更を書き込む必要があります。また、必要なクォートロジックを書き直す必要があります。

関連する問題