简体   繁体   中英

Mongo not working with nodejs

I'm working on a simple problem to insert a collection in a Mongo database using Node.js . However I am facing two problems:

1. When I use {safe: true} in the .insert function
(below: albums.insert(a1, {safe: false}, cb);
and albums.insert(a2, {safe: false}, cb); ), the collections dont get inserted in the database ie they dont get printed on the terminal when I do console.log(doc) (please see the program below)

2. The program does not end by itself, I have to press ctrl+c to end it, even though it has db.close() at the end and I can see "here" printed on the terminal which is console.logged after db.close()

Any help is much appreciated, thanks!

var Db= require('mongodb').Db,
Connection= require('mongodb').Connection,
Server= require('mongodb').Server,
async= require('async');

var host= "localhost";
var port= Connection.DEFAULT_PORT;

var db= new Db("PhotoAlbums", new Server(host, port, {auto_reconnect: true,
        poolSize: 20}), {w: 1});

var a1= {_id: "Travel", name: "Travel", title: "Travelogues", description:        
"This was great", date: "1/1/2014"}, 
a2= {_id: "friends", name: "friends", title: "Friends", description:   
"Random Pics", dat: "2/1/2014"};

var albums, photos;

async.waterfall([

function(cb)
{
    db.collection("Albums", cb);    
}, 

function (albums_coll, cb)
{
    albums= albums_coll;
    db.collection("Photos", cb);
},

function (photos_coll, cb)
{
    photos= photos_coll;
    albums.insert(a1, {safe: false}, cb);
},

function (doc, cb)
{ 
    console.log("1. Successfully wrote ");
    console.log(doc);
    albums.insert(a2, {safe: false}, cb);   
},

function (docs, cb)
{ 
    console.log("2. Successfully wrote ");
    console.log(docs);
    cb(null);
},

], function(err, results)
{ 
    if(err)
     console.log("ERROR!");
    db.close();
    console.log("here");
});

Essentially you never connected to the database. The Db object needs the .open() method to be called and all interaction to occur within the provided callback of that method or otherwise within the "connection" event handler.

There are also a few concepts where you are a little off the mark here that I'd like to set you straight on. First a revised listing:

var async = require('async'),
    MongoClient = require('mongodb').MongoClient;


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

  var a1 = {
    "_id": "Travel",
    "name": "Travel",
    "title": "Travelogues",
    "description": "This was great",
    "date": new Date("2014/01/01")
  },
      a2 = {
    "_id": "friends",
    "name": "friends",
    "title": "Friends",
    "description": "Random Pics",
    "date": new Date("2014/01/02")
  };

  var albums;

  async.waterfall(
    [
      function(cb) {
        db.collection("albums",cb);
      },

      function(albums_col,cb) {
        albums = albums_col;
        albums.insert(a1,cb);
      },

      function(doc,cb) {
        console.log("1. Successfully wrote");
        console.log(doc);
        albums.insert(a2,cb);
      },

      function(doc,cb) {
        console.log("2. Successfully wrote");
        console.log(doc);
        cb();
      }
    ],
    function(err,results) {
      if (err) throw err;
      db.close();
    }
  );
});

First, you should be using MongoClient in new code. It's a standard implementation across all langauges. You can still use a Server object if you want, but the connection string should suffice normally. Alternately:

MongoClient.connect( new Server( 
    "localhost",
    Connection.DEFAULT_PORT,
    { "auto_reconnect": true }
    { w: 1 }
),function(err,db) {

    {...}
});

Another part is that I am dropping options that are already set by default. Changing connection pool options doesn't really make sense for a listing such as this, but there is already a default 5 connections built into the driver without specifying this. Also the "WriteConcern" or { w: 1 } is the default.

Secondly in the structures specified for the documents, use real date objects. These will serialize into MongoDB as "date" types for BSON storage, and they come back into your code when read as real date objects as well. This is what you want to do with dates. Otherwise these are just strings and not very useful.

Not a big fan of declaring a variable for the collection as opposed to passing the parameter to the callback, but keeping that the same for brevity.

Noting here the omission of the { safe: true } from the WriteConcern portion of the .insert() methods. Unless you really want override what the setting was for the connection already is ( and you should rarely want to ) then you probably just want to use the default. The "safe" option is also deprecated, so you should be writing { w: 0 } which is the equivalent.

But to finally note, if you do choose { w: 0 } then your expected "response" of the document that was written will not be returned. The value will be reported as null even though it was written to the database. This is because this "unsafe" way of writing does not require any acknowledgement from the database. So you are just assuming it's there, and therefore probably want the default which is { w: 1 } already, and that means it's confirmed.

The output is then as expected:

1. Sccessfully wrote
[ { _id: 'Travel',
    name: 'Travel',
    title: 'Travelogues',
    description: 'This was great',
    date: Wed Jan 01 2014 00:00:00 GMT+1100 (AEDT) } ]
2. Sccessfully wrote
[ { _id: 'friends',
    name: 'friends',
    title: 'Friends',
    description: 'Random Pics',
    date: Thu Jan 02 2014 00:00:00 GMT+1100 (AEDT) } ]

Of course depending on the actual timezone you are in for stringified output. Also note that the forms of new Date("2014/01/01") and new Date("2014-01-01") are not equal. The first will construct the date as a UTC timezone object, and the second will construct in your local timezone. MongoDB will store a UTC, so it is best to make sure your construction is formed that way for any data you store.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM