2012-03-30 4 views
1

Я знаю, что это должно быть легко, но я просто не могу понять, как это сделать, несмотря на то, что он провел несколько часов, глядя на него сегодня. Насколько я могу судить, нет прямого примера или учебника онлайн.Создание представления CSV от CouchDB

У меня есть несколько «таблиц» документов в базе данных CouchDB, причем каждая «таблица» имеет другое значение в поле «схема» в документе. Все документы с той же схемой содержат одинаковый набор полей. Все, что я хочу сделать, это просмотр различных «таблиц» в формате CSV, и я не хочу указывать список имен полей в каждой схеме.

Выход CSV будет потребляться сценарием R, поэтому я не хочу, чтобы на выходе были какие-либо дополнительные заголовки, если я могу их избежать; просто список имен полей, разделенных запятыми, со значениями в формате CSV.

Например, две записи в формате "table1" может выглядеть следующим образом:

{  
    "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) 
    } 
}" 

как я хочу для сортировки моих записей в заказе timestamp.

Предположительно функция списка будет что-то вроде:

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

В отличие от предложения Райана, поля, которые будут включены в список, не могут быть сконфигурированы в этой функции, и любые изменения в порядке или включены поля должны быть записаны. Вам также придется переписать любую требуемую логику цитирования.

Смежные вопросы