0

Im using MongoDB query within JS function. The script looks like this:

var continous = ['b', 'e', 'LBE'];

continous.forEach(e => izracun(e));

function izracun(atr) {
    var query1 = { "$match": { [atr]: {"$ne" : -1} } };
    var query2 = { "$group": { "_id": atr, "avg": { "$avg": "$"+[atr] }, "stdev": { "$stdDevPop": "$"+[atr] }, "nonMissing": { "$sum": 1 }}};

    db.ctg.aggregate([query1, query2]); 
}

When I execute it in mongo shell with load("script.js"), the shell returns "true". I tried using the query with fixed parameter values (instead of passing arguments) inside the function, but I still don't get the results (returns "true" only) that should look like example below:

{ "_id" : "b", "avg" : 878.4397930385701, "stdev" : 893.8744489449962, "nonMissing" : 2126 }

If I console log the query and run it directly in mongo shell, it works fine.

What am I doing wrong?

EDIT: I tried handling the promise with:

db.ctg.aggregate([query1, query2]).then(function (results) { //this block will run synchronsly to the aggregate statement
    console.log(results);
}); 

Im getting the following error:

uncaught exception: TypeError: db.ctg.aggregate(...).then is not a function

1
  • 1
    The statement db.ctg.aggregate([query1, query2]) returns a promise. You need to handle the promise via a .then(results => { // Code here }). All-in-all, it looks like: db.ctg.aggregate([query1, query2]).then(results => { // Code here }) Commented Jan 28, 2020 at 16:04

1 Answer 1

1

The query returns a promise and then runs asynchronously in the background while the rest of your code carries on - you could change the code to be like the below to get an output:

var continous = ['b', 'e', 'LBE'];

continous.forEach(e => izracun(e));

function izracun(atr) {
   var query1 = { "$match": { [atr]: {"$ne" : -1} } };
   var query2 = { "$group": { "_id": atr, "avg": { "$avg": "$"+[atr] }, "stdev": {"$stdDevPop": "$"+[atr] }, "nonMissing": { "$sum": 1 }}};

    db.ctg.aggregate([query1, query2]).then(function (results) { //this block will run synchronsly to the aggregate statement
        console.log(results);
    }); 
    console.log("after"); //<-- this will apear before the results do despite being after it
}

If you need the function to wait on the query you could look at async/await (https://javascript.info/async-await) or your could return the promise and handle that elsewhere it depends on the greater context of your code.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm getting the following error if I try .then() : uncaught exception: TypeError: db.ctg.aggregate(...).then is not a function
Hi, Sorry it could be that you are using a different driver can you try db.ctg.aggregate([query1, query2], function(err, result) { console.log(results)}); instead and see if that works?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.