【问题标题】:How to access child element of json object using node.js如何使用 node.js 访问 json 对象的子元素
【发布时间】:2015-02-05 22:37:26
【问题描述】:

在我的 node.js 应用程序中,我从 mongodb 服务器检索值并希望将它们转换为 CSV 文件。父元素很容易从数据库中访问并显示在 CSV 文件中,但子元素不显示并且可以无法访问..

JSON 结构:

"name" : "fhj",
"age" : "23",
"gender" : "female",
"sec" : "b",
"username" : "9886666",
"language" : "HINDI",
"method" : "method2",
"timeSlot" : {
    "id" : 2,
    "fromTime" : 12,
    "toTime" : 15
}

我的代码:

db.users.find(function(err,values){
if(err||!values.length)
   console.log("ERROR !!!!");
else
{ 
   var i=1;
   str='[';
   values.forEach(function(user){
     if(i==values.length)
         str=str+'{ "name" : "' + user.username + '","age" : "'+ user.age +'","gender":"'+user.gender+'","sec":"'+user.sec+'","username":"'+user.username+'","language":"'+user.language+'","method":"'+user.method+'","Timeslot":"'+user.timeslot+'"}';
     else{
       str = str + '{ "name" : "' + user.username + '","age" : "'+ user.age +'","gender":"'+user.gender+'","sec":"'+user.sec+'","username":"'+user.username+'","language":"'+user.language+'","method":"'+user.method+'","Timeslot":"'+user.timeslot+'"},' +'\n';
       i++;
     }
   });
   str = str.trim();
   str = str + ']';
   var obj=JSON.parse(str);
   json2csv({data: obj, fields: ['name', 'age','gender','sec','username','language','method','Timeslot']}, function(err, csv) {
      if (err) 
          console.log(err);
      fs.writeFile('./files/user.csv', csv, function(err) {
         if (err) 
             throw err;
         console.log('File saved');
      });
   });
 }  
});

除了timeslot的子元素外,所有的值都会显示出来。 如何从数据库中访问 JSON 的子元素并在 CSV 文件中显示所有值???

【问题讨论】:

  • 能否提供创建的user.csv文件。我遇到了与 json2csv 模块类似的问题。对于内部嵌套对象/数组,它不支持复杂结构。
  • @SaleemAhmed 你必须手动为嵌套的 json 创建 csv。

标签: json node.js csv


【解决方案1】:

访问嵌套元素的简单方法可以在following thread 的答案中找到(访问嵌套数据结构)。

嵌套数据结构是引用其他数组或对象的数组或对象,即它的值是数组或对象。可以通过连续应用点或括号符号来访问此类结构。

我们可以看到 timeSlot 是一个对象,因此我们可以使用点符号来访问它的属性。 items 属性的访问方式如下:

timeSlot.id

或者,我们可以对任何属性使用括号表示法,特别是如果名称中包含的字符会使其对点表示法的使用无效:

var item_name = timeSlot['id'];

获得所需的所有数据后,CSV 文件的创建应该非常简单:)

【讨论】:

    【解决方案2】:

    像下面这样试试

        db.users.find(function(err, users){
            if (err || !users.length) 
                return console.log(err || 'Users not found');
    
            // List of column to export to cvs
            var columns = ['name', 'age', 'gender', 'sec', 'username', 'language', 'method', 'timeSlot'];   
    
            var text = users.reduce(function(text, user){
                // user is object e.g. {name : "fhj", age : "23", .. }
                // If user is json then `user = JSON.parse(user, columns);`
    
                // convert user to csv-line
                text += columns.reduce(function(line, col){
                    // I'm don't know how timeSlot must be save => save as json
                    line += (type user[col] == 'object') ? JSON.stringify(user[col], ['id', 'fromTime', 'toTime']) : user[col];
                    line += ';';
                    return line;
                }, '') + '\n';
    
                return text;
            }, '');
    
            fs.writeFile('./files/user.csv', text, function(err) {
                if (err) 
                    throw err;
    
                console.log('File saved');
            });
        });
    

    【讨论】:

      【解决方案3】:

      尝试使用 user.timeslot.fromTime && 为每个子元素创建一个键/值

      【讨论】:

      • 它显示错误:无法读取未定义的属性'fromTime'
      【解决方案4】:

      试试这样。这会将 timeSlot 对象中的所有数据合并为单个字符串。您可以根据需要格式化该字符串。在 forEach 循环中添加代码。

      var strToAdd = "";
      for (var k in timeSlot) {
      strToAdd += k + timeSlot[k] + "->";
      }
      
      ...+"Timeslot":"'+strToAdd+'"....
      

      希望这会有所帮助。

      【讨论】:

        【解决方案5】:

        似乎问题在于,在您迭代变量values 的forEach 循环中,您访问的是user 的属性timeslot,而不是user 的值timeSlot。记住区分大小写很重要!

        Here is a fiddle which demonstrates that changing the case of the object property in lines 24 and 25 solves the issue

        在链接的示例中,我还对该对象进行了字符串化,以便可以将其写入文档并清楚地查看输出。我建议不要这样做,因为您稍后可能会遇到解析它的问题。相反,您应该通过访问该对象的属性来构造一个字符串。

        无论如何,您出错的原因是原始代码中存在区分大小写的问题。我希望这有帮助。

        【讨论】:

          【解决方案6】:

          当您读取结构化数据(此处:JSON)并希望将其转换为扁平数据(此处:csv)时,您必须决定如何执行扁平化。

          换句话说 - 您的 csv 目标结构可能如下:

          name, age, gender, sec, username, language, method, timeSlot_id, timeSlot_fromTime, timeSlot_toTime
          "fhb","23","female","b","9886666","HINDI","method2",2,12,15
          

          一旦您决定要以这种方式展平 timeSlot 中给出的结构,您就可以使用@Aikon Mokwai 中的注释而不使用 stringify - 使用@trolologuy 描述的数组表示法来阅读结构:

          var timeSlot_id = timeSlot['id]';
          var timeSlot_fromTime = timeSlot['fromTime'];
          var timeSlot_toTime = timeSlot['toTime'];
          

          随后,读取 csv 的人必须了解您将数据展平但不必解析任何结构,因为您确实提供了平面数据记录(因为 csv 最喜欢它)。

          希望对你有帮助!

          【讨论】:

            【解决方案7】:

            您好使用异步 foreach 循环来实现上述。以下是其工作原理的详细信息。

            Async loop in nodejs

            【讨论】:

              【解决方案8】:
              var json= {
              "name" : "fhj",
              "age" : "23",
              "gender" : "female",
              "sec" : "b",
              "username" : "9886666",
              "language" : "HINDI",
              "method" : "method2",
              "timeSlot" : {
                  "id" : 2,
                  "fromTime" : 12,
                  "toTime" : 15
               }
              };
              console.log(json.timeSlot['id']);
              console.log(json.timeSlot['fromTime']);
              console.log(json.timeSlot['toTime']);
              

              享受:)

              jsfiddle

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-09-27
                • 1970-01-01
                • 2021-10-10
                • 2019-09-30
                • 1970-01-01
                • 2013-01-31
                • 2017-12-10
                相关资源
                最近更新 更多