Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

toArray undefined in NodeJS and MongoDB


I am trying to run an aggregation MongoDB and Nodejs, but I have some difficulties in running the project. When I enter the following command in the MongoDB shell:

 db.data.aggregate([{$match: {}},{$group: {'_id': '$State', 'total': {'$sum': 1}} }]).toArray() 

then I am getting the expected output.
However, when I use the following little Nodejs program

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

MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
  if(err) throw err;

  console.log("Connected correctly to server");

  var col=db.collection('data');

  col.aggregate([{$match: {}},{$group: {'_id': '$State', 'total': {'$sum': 1}} }])
    .toArray(function(err, result) {     
       if(err) throw err;
       console.log(result);             
    });

  db.close();

});

then I am getting the error message: 'TypeError: Cannot read property 'toArray' of undefined'

Could somebody please help me?

Many thanks in advance, Andi

like image 913
Andi Maier Avatar asked Sep 11 '15 19:09

Andi Maier


2 Answers

As @ExplosionPills correctly pointed out, your code won't work as the logging is done asynchronously and after the connection is closed so you could try removing the db.close() line or create a function that makes use of a callback function to returns the aggregation results:

var aggregateStates = function(db, callback) {
   db.collection('data').aggregate(
     [
         { $group: { "_id": "$State", "total": { $sum: 1 } } }
     ]
   ).toArray(function(err, result) {
         console.log(result);
         callback(result);
   });
};

Call the aggregateStates function:

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
    aggregateStates(db, function() {
        db.close();
    });
});
like image 153
chridam Avatar answered Oct 13 '22 23:10

chridam


According to mongo-native driver doc, aggregate() returns null. Therefore, toArray() cannot be called from what it returns. However, aggregate() takes a callback which has the result of aggregate() if successful. So here is the revised code:

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

MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
    if(err) throw err;

    console.log("Connected correctly to server");

    var col=db.collection('data');

    col.aggregate([
        {$match: {}},
        {$group: {'_id': '$State', 'total': {'$sum': 1}} }
    ], function(err, result) {
        if(err) {
            db.close();
            throw err;
        }
        console.log(result);
        db.close();
    });

});
like image 1
Ben Avatar answered Oct 13 '22 23:10

Ben