0

It's a continuation of question from here . My aim is to update all the documents with minimum score.

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

var mongoclient=new MongoClient(new server("localhost",27017));

mongoclient.connect("mongodb://localhost:27017/school",function(err,db){

var db=mongoclient.db('school');
cursor=db.collection('students').aggregate(
[
  {$match : {"scores.type" : "homework"}},
  {$unwind:"$scores"},
  {$group : {_id : '$name','minimum' : { $min :"$scores.score"  }}}
], function(err, result) {   // callback
        console.dir(result);
    }
);
cursor.each(function(err,doc)
{
db.collection('students').update({'_id':doc._id},{$pull:{'scores':{'score':doc.minimum}}});
});
});

Using this i am getting error

node app.js 
undefined

/home/oroborus/node_modules/mongodb/lib/mongodb/mongo_client.js:475
          throw err
                ^

TypeError: Cannot call method 'each' of undefined
        at /home/oroborus/hw3-1/app.js:18:8
        at /home/oroborus/node_modules/mongodb/lib/mongodb/mongo_client.js:83:5
        at /home/oroborus/node_modules/mongodb/lib/mongodb/mongo_client.js:472:11
        at process._tickCallback (node.js:415:13)

According to previous programs written by me and the post above this looks correct then still why does this error persists ?
[Edit]
When i did console.dir(cursor) it said undefined. Why ? This might be because of the asynchronous behaviour of Node.js but how do i rectify it. How do i make it synchronous.
Thanks

Community
  • 1
  • 1
Saras Arya
  • 3,022
  • 8
  • 41
  • 71

1 Answers1

0

collection.aggregate() is asynchronous, aggregate won't return a cursor until it's done, which is in its callback. I don't think aggregate() actually returns a cursor. The result should be in 'result' of the callback, but if it does and if you need to iterate through it, the code should be in its callback:

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

var mongoclient=new MongoClient(new server("localhost",27017));

mongoclient.connect("mongodb://localhost:27017/school",function(err,db){
  cursor=db.collection('students').aggregate(
    [
        {$match : {"scores.type" : "homework"}},
        {$unwind:"$scores"},
        {$group : {_id : '$name','minimum' : { $min :"$scores.score"  }}}
    ], function(err, result) {   // callback
        console.dir(result);

        if (cursor) {
            cursor.each(function(err,doc)
            {
                db.collection('students').update({'_id':doc._id},{$pull:{'scores':{'score':doc.minimum}}});
            });     
        }


    }
  );
});

Update: Just read the document and aggregate() doesn't return a cursor (unless it's 2.6 or greater, option can be specified to return cursor): http://mongodb.github.io/node-mongodb-native/api-generated/collection.html

Ben
  • 5,024
  • 2
  • 18
  • 23
  • 1
    have a look [here](http://stackoverflow.com/questions/23955533/what-aggregation-cursor-methods-are-supported-by-nodejs-drivers) – Saras Arya Apr 05 '15 at 01:16
  • it looks like you can get the cursor on 2.6+. we have all node server on openshift and openshift is using mongodb 2.4, so I didn't know about that... Thanks for the link Saras... – Ben Apr 05 '15 at 05:11
  • i am using 2.6.9 i cursor.on function is working for me but the normal method to update data won't work i guess. I need how to update.. I am not able to find that :( – Saras Arya Apr 05 '15 at 10:56