Picci Picci - 3 months ago 11
Node.js Question

MongoDB - running parallel queries with nodejs driver and close the db connection when the last query completes

I need to run several queries against MongoDB in parallel using the node.js driver.

Currently I am using a counter which gets decreased any time a query gets completed. When the counter reached 0 it means that all queries have completed and then I close the db connection.

In a simple case with 2 queries running in parallel the code is the following

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

MongoClient.connect("mongodb://localhost:27017/company", function(err, database) {
if(err) throw err;
db = database;

let collection = "resumes";
let numberOfParallelQueries = 2;
let result = [];
let finalCallback = (err, resp) => {
if (err) throw(err);
numberOfParallelQueries = numberOfParallelQueries -1;
result.push(resp);
if (numberOfParallelQueries == 0) {
console.log(result);
db.close()
};
}
db.collection(collection).find({"jobs": {$elemMatch: {"company": "CNA", position: "director"}}}).toArray(finalCallback);
db.collection(collection).find({$and: [{"jobs.company": "CNA"}, {"jobs.position": "director"}]}).toArray(finalCallback);
});


My question is whether there any more elegant solution. I am thinking about something in the line of
forkJoin()
method of
Observable
.

Thanks in advance

Answer

That's what Promises are for:

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

MongoClient.connect("mongodb://localhost:27017/company", function(err, database) {
    if(err) throw err;
    db = database;

    let collection = "resumes";
    Promise.all([
        queryPromise(collection, {"jobs": {$elemMatch: {"company": "CNA", position: "director"}}}),
        queryPromise(collection, {$and: [{"jobs.company": "CNA"}, {"jobs.position": "director"}]})

    ]).then(function(result) {
        // result is an array of responses here
        db.close();
    }).catch(function(err) {
        console.log(err);
        db.close();
    });


    function queryPromise(collection, query) {
        return new Promise(function(resolve, reject) {
            db.collection(collection).find(query).toArray(function(err, resp) {
                if (err) {
                    reject(err);
                } else {
                    resolve(resp);
                }
            });
        })
    }
});
Comments