0

it should be a simple issue - I'm new with mongodb , but I'm still stuck on this . Same query in nodeJS returning 0 in aggegate, but seems to be ok in shell

in mongodb I have a donations collection

/* 1 */
{
"_id" : ObjectId("5b9b625c0ffcdb7c339a8961"),
"username" : "abc@xyz.com",
"amount" : 500,
"badge" : true,
"addedAt" : 1536909914979.0,
"first_name" : "john",
"last_name" : "Doe",
"email" : "abc@xyz.com"
}

/* 2 */
{
    "_id" : ObjectId("5b9b62e00ffcdb170b9a8962"),
    "username" : "abc@xyz.com",
    "amount" : 5000,
    "badge" : false,
    "addedAt" : 1536910048238.0,
    "first_name" : "John",
    "last_name" : "Doe",
    "email" : "abc@xyz.com"
}

Testing query in mongodb shell, results are as expected:

db.getCollection('donations').aggregate([
{
    '$group' : {
            '_id' : null,
            'total_donations' : {'$sum' : "$amount"}
        }
}
])

RESULT:

    /* 1 */
{
    "_id" : null,
    "total_donations" : 5500
}

In NodeJS I have :

connectToDb(dbUri).then(function (db) {
        db.collection('donations').find().sort(sorting).limit(limit).toArray(function (err, arr) {

            if (err) {
                console.log(err)
                res.status(500).json({
                    message: "Failed to fetch donations"
                }).end();
            } else {
                var allDonations = {};               
                var query = [
                    {
                        '$group' : {
                                '_id' : null,
                                'total_donations' : {'$sum' : "$amount"}
                            }
                    }
                ];
                db.collection('bottles').aggregate(query).toArray(function(err, result){
                    if(err) console.log(err);
                    allDonations['total_donations'] = result[0].total_donations;   
                    allDonations['donations'] = arr;                     
                    console.log(allDonations);
                });                
            }
        });

The result[0].total_donations here is returning as 0 anything I'm missing here ?

UPDATE 1

As suggested by Anthony in the comments, I have changed the code to below:

 connectToDb(dbUri).then(function (db) {
        var query = [
                            {
                                '$group' : {
                                        '_id' : null,
                                        'total_donations' : {'$sum' : "$amount"}
                                    }
                            }
                        ];
        db.collection('bottles').aggregate(query).then(result => {                      
            console.log(result);
        })
        .catch(error =>{
            console.log(error);
        });      
    });

but now i get the following error:

(node:16708) UnhandledPromiseRejectionWarning: TypeError: db.collection(...).aggregate(...).then is not a function
warning.js:18
Danish
  • 741
  • 4
  • 17
  • 31
  • remove `.toArray()` – Ashh Sep 21 '18 at 10:30
  • if i don't do toArray, the result is an aggregate cursor instance, so to get the results - it needs to be toArray(function(err, result){...}) - as far as I've been able to read from the documentation, result after removing toArray: result[0].total_donations TypeError: Cannot read property 'total_donations' of undefined – Danish Sep 21 '18 at 10:31
  • You don't need to use `toArray()` cursor in aggregate query. If you want result from an aggregate cursor use promise or async await instead. `db.collection.aggregate([]).then((result) => { console.log(result) })` – Ashh Sep 21 '18 at 10:51
  • modified the code - question is updated, now getting an error that .then is not defined – Danish Sep 21 '18 at 11:24
  • Problem is with your mongodb native driver version. [**This**](https://stackoverflow.com/questions/47662220/db-collection-is-not-a-function-when-using-mongoclient-v3-0) might help you – Ashh Sep 21 '18 at 11:31
  • 1
    not sure it comes from driver : as find method, aggregate doen't return a Promise if no callback provided, but always return a cursor. So toArray (or loop with cursor.next()) is required to access data. – matthPen Sep 21 '18 at 13:47
  • 1
    Just a question : your aggregation is on 'bottles' collection, or 'donations'? collection name is different between mongo shell and node code! Ctrl-c / Ctrl-v issue perhaps... – matthPen Sep 21 '18 at 13:49
  • @matthPen - you nailed it - last night I was sleepy during debugging - this is basically a lambda, which I copy paste into a local js file to test the logic - so this mistake happened in copy paste - – Danish Sep 22 '18 at 01:15
  • the story sounds so familiar for me... – matthPen Sep 22 '18 at 07:59

0 Answers0