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

8
我正在通过Wundground的API以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");
      });
    });

以下是JSON格式的天气数据的小节选:

{ "current_observation": {
    "image": {
    "url": "http://icons-ak.com/graphics/logo.png",
    "title": "Weather Underground"
    },
    "display_location": {
    "full":"My City, State",
    "city":"My City",

我需要在将数据保存到Mongo之前解析它吗?那么我错过了什么。正如我所说,如果我将所有天气数据输出到控制台,所有数据都会完美地显示出来,我只是在Node.JS和MongoDB之间做错了什么。

谢谢。

更新***

我尝试以这种方式解析"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");`

似乎那也行不通。我会再次查看它。


看起来你有一个字符串,请解析它! - tymeJV
2个回答

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

关于这个问题,你已经为end事件注册了一个监听器,这是很好的,但是你在每个data事件上都添加了一个新的监听器!这意味着如果你收到5个data事件,你将调用5次该函数,将对象添加到MongoDB...在上面的片段中,请注意我已经将response.on('end', function() {…})移到了response.on('data')回调的外部。


我早有怀疑并尝试过那个方法(请参见原帖的更新)。不过我还是缺少了些什么。我会回去再试一次。 - Godfried
刚刚执行了 Json.parse(str),结果 Node 抛出了一个错误: undefined:43 "obser SyntaxError: Unexpected token o - Godfried
2
有道理。看看我的修改:你会得到一个SyntaxError,因为你试图解析一个不完整的字符串。在解析之前等待“end”事件。 - Paul Mougel

0
var MongoClient = require('mongodb').MongoClient, format = require('util').format;

MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err,db) {

    if (err) throw err;
    console.log("Connected to Database");
    var document = {name:"David", title:"About MongoDB"};

    // insert record
    db.collection('test').insert(document, function(err, records) {
        if (err) throw err;
        console.log("Record added as " + records[0]._id);
    });
});

参考自: http://code.runnable.com/UW3ef2Tkq498AABE/insert-a-record-in-mongodb-using-mongodb-native-for-node-js


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接