在 Cloudant 中使用列表和视图将 JSON 数据转换为 CSV

Converting JSON data to CSV in Cloudant using List and View

我尝试使用 List 函数将 Cloudant 数据库中的 JSON 数据转换为 csv 格式。它适用于除 JSON 数组值以外的所有值,即嵌套值。对于这些,我将 [object object] 作为我的 csv 文档中的输出。

请在下面找到我正在使用的示例 JSON 文档:

  {
    "NAME": "Aparna",
    "EMAIL": "something@domain.com",

    "PUBLIC_OFFICIALS_CONTACTED": [
    { "NAME_PUBLIC_OFFICIAL": [ "ab"],
    "TITLE_PUBLIC_OFFICIAL": ["cd"]}
    ],
    "COMMUNICATION_TYPE": [
    "Meeting",
    "Phone",
    "Handout",
    "Conference"
    ],
    "NAMES_OF_OTHERS_FROM_IBM": [
    { "NAME_OF_OTHERS": ["ef"],
    "TITLE_OF_OTHERS": [ "gh"]}
    ],
    "COMMUNICATION_BENEFIT": "Yes",
    "LAST_UPDATE_BY" : "ap"
    }

Please find the map and list functions used below :


     "map" : "function(doc){
                                 if((\"SAVE_TYPE_SUBMIT\" in doc) && (doc.SAVE_TYPE_SUBMIT== \"Submit\")) {
                                    emit (doc. LAST_UPDATE_BY,[doc.NAME,doc.EMAIL,doc.PUBLIC_OFFICIALS_CONTACTED[0].NAME_PUBLIC_OFFICIAL,\n   doc.PUBLIC_OFFICIALS_CONTACTED[0].TITLE_PUBLIC_OFFICIAL,doc.COMMUNICATION_TYPE,doc.NAMES_OF_OTHERS_FROM_IBM[0].NAME_OF_OTHERS,  doc.NAMES_OF_OTHERS_FROM_IBM[0].TITLE_OF_OTHERS, doc.COMMUNICATION_BENEFIT,doc. LAST_UPDATE_BY,doc.LAST_UPDATE_DATE]) ;
                                  }
                              }



"list" : "function (head, req) {
                     var row;
                     start({\n headers: {'Content-Type': 'text/csv' }, 
                        });
                     var first = true;
                     while(row = getRow()) {
                         var doc = row.doc;
                         if (first) {
                            send(Object.keys(doc).join(',') + '\n');
                            first = false;\n }
                            var line = '';
                            for(var i in doc) {
                           // comma separator
                               if (line.length > 0) {
                                  line += ',';\n }
                                  // output the value, ensuring values that themselves
                                 // contain commas are enclosed in double quotes
                                    var val = doc[i];
                                    if (typeof val == 'string' && val.indexOf(',') > -1)                            {
                                         line += '\"' + val.replace(/\"/g,'\"\"') + '\"';
                                     } 
                                   else {
                                       line += val;
                                        }
                                 }
                                 line += '\n';
                                 send(line);
                             }}"

注意:在地图中,目前只从 JSON 数组中提取第一个值,目的是为了简化函数。

请帮助了解如何获取嵌套的 JSON 值或数组并以 csv 格式下载它们。任何指导将不胜感激!

您可以尝试将要导出的对象字符串化,您会得到一些线索

if (typeof val == 'string' && val.indexOf(',') > -1)                            {
    line += '\"' + val.replace(/\"/g,'\"\"') + '\"';
} 
else {
    line += JSON.stringify(val);
}

甚至更好

if (typeof val == 'string' && val.indexOf(',') > -1)                            {
    line += '\"' + val.replace(/\"/g,'\"\"') + '\"';
} 
else if(val instanceof Array){
    line += val.join(',');
}
else {
    line += JSON.stringify(val);
}

此处有几处更改可能会有所帮助。第一件事是你不需要发出所有你想使用的值,因为你可以在处理视图时从列表中访问文档本身。

考虑到这一点,地图可以像

那样发射

emit (doc.LAST_UPDATE_BY, null);

有了这个,如果您使用 include_docs=true 请求 list/view,那么您可以像这样在 while(row = getRow()) 部分中引用文档中的字段:

send(row.doc.NAME + ',' + row.doc.EMAIL + '\n');

对于嵌套文档,尝试类似的方法:

row.doc.PUBLIC_OFFICIALS_CONTACTED.0.NAME_PUBLIC_OFFICIAL

您已经在另一个问题中提到了我推荐的完整工作示例文章 https://developer.ibm.com/clouddataservices/2015/09/22/export-cloudant-json-as-csv-rss-or-ical/ - 希望这个解释也能有所帮助。