将Node.js中的JSON数据存储到MongoDB

God*_*ied 8 javascript json mongodb node.js

我正在通过他们的API从Wundground以JSON格式提取天气数据,没有任何问题.我正在尝试将这些数据存储在MongoDB中供以后使用.我实际上得到了数据,并能够将它写入Mongo的集合中.但是,当我执行db.collection.find()时,它几乎看起来像是单独保存每个单独的字符而不是JSON格式.这是获取数据的代码片段,应该保存到Mongo:

// Define the Wunderground method.
var method = "/api/" + apiKey + "/conditions/q/" + state + "/" + city + ".json";

// Define the HTTP post properties.
var options = {
  host: 'api.wunderground.com',
  path: method,
  method: 'GET',
  port: 80
};

// Create the HTTP POST.
var request = http.request(options, function (response) {
  var str = '';

  // Create the listener for data being returned.
  response.on('data', function (chunk) {
    str += chunk;


    // Create the listener for the end of the POST.
    response.on('end', function (){
      db.collection('weathercollection').save(str, function(err, records) {
        if (err) throw err;
        console.log("record added");
      });
    });
Run Code Online (Sandbox Code Playgroud)

JSON格式的天气数据的一小部分摘录:

{ "current_observation": {
    "image": {
    "url": "http://icons-ak.com/graphics/logo.png",
    "title": "Weather Underground"
    },
    "display_location": {
    "full":"My City, State",
    "city":"My City",
Run Code Online (Sandbox Code Playgroud)

我应该在保存到Mongo之前解析数据吗?所以我错过了什么.正如我所说,如果我输出到控制台所有的天气数据显示完美,我似乎在Node.JS和MongoDB之间做错了.

谢谢.

UPDATE***

我确实尝试用这种方式解析"str"

// Create the listener for data being returned.
response.on('data', function (chunk) {
str += chunk;

var jsonResult = JSON.parse(str);

// Create the listener for the end of the POST.
response.on('end', function (){
  db.collection('weathercollection').save(jsonResult, function(err, records) {
    if (err) throw err;
    console.log("record added");`
Run Code Online (Sandbox Code Playgroud)

这似乎也没有用.我会再看一遍.

Pau*_*gel 13

是的,您需要为您的send函数提供一个JavaScript对象(参见MongoDB本机驱动程序文档,它看起来就像您正在使用的那样),但是您发送一个字符串(这就是为什么您可以在每个data事件上连接它).您必须使用将字符串转换为完整对象JSON.parse(str).

如果你想以确保数据你处理的类型,打印的结果typeof strtypeof JSON.parse(str).

编辑:您的代码中有第二个问题.该response对象实际上是一个,这意味着它在收到数据时会发出数据.这也意味着您可以data多次收到该活动.这就是您需要:

  1. 创建一个空字符串
  2. 在每个data事件上,将刚刚收到的块连接到字符串
  3. 当您确定不会再收到任何数据时,只会尝试在最后解析它.

在您提供的更新的代码段中,您尝试在第一个数据事件上解析字符串,但这可能是一个不完整的字符串.

以下是实现此目的的正确方法:

var str = '';
response.on('data', function(chunk) {
  str += chunk;
});
response.on('end', function() {
  var myObject = JSON.parse(str);
  // Send the Mongo query here
});
Run Code Online (Sandbox Code Playgroud)

与此问题相关,您还注册了一个end事件的监听器,这很好,但您在每个data事件上添加了一个新的监听器!这意味着如果您收到5个数据事件,您将调用将该对象添加到MongoDB的函数的5倍...在上面的代码段中,请注意我已经移动response.on('end', function() {…})response.on('data')回调的外部.

  • 说得通.看看我的编辑:你得到一个SyntaxError,因为你试图解析一个不完整的字符串.在解析之前等待`end`事件. (2认同)