Node.JS, Express & MongoDB :: Multiple Collections Node.JS, Express & MongoDB :: Multiple Collections mongodb mongodb

Node.JS, Express & MongoDB :: Multiple Collections


Ok, using aesede's solution plus my own tinkering, I got it to render two collections. It could probably use some finessing but here's what I got:

// GLOBAL ARRAYS FOR STORING COLLECTION DATAvar collectionOne = [];var collectionTwo = [];app.get('/', function(req, res){  MongoClient.connect("mongodb://localhost:27017/michael", function(err, db) {    if(!err) {      console.log("We are connected");    }    db.collection("collectionOne", function(err, collection) {      collection.find().sort({order_num: 1}).toArray(function(err, result) {        if (err) {          throw err;        } else {          for (i=0; i<result.length; i++) {            collectionOne[i] = result[i];          }        }      });      db.collection("collectionTwo", function(err, collection) {        collection.find().sort({order_num: 1}).toArray(function(err, result) {          if (err) {            throw err;          } else {            for (i=0; i<result.length; i++) {              collectionTwo[i] = result[i];            }          }        });      });      // Thank you aesede!      res.render('index.html', {        collectionOne: collectionOne,        collectionTwo: collectionTwo      });    });  });});

The only bug, per se, that I found, was that when Node restarted and I hit "refresh" in the browser, I didn't see any content being rendered in the HTML. However, any subsequent refresh showed the content consistently.


There is actually a really simple, intuitive answer to this problem. It's definitely not elegant and I do think an update to Express, Mongoose and NodeJS should include a preset way of doing this rather than having to logically think the process through.

All you have to do is nest your find() calls into each other for each collection you want to pass through to the page. Example below:

app.get("/", function(req, res) {     Collection.find({}, function(err, collection) {          if(err) {               console.log(err);          } else {               Collection2.find({}, function(err, collection2) {                    if(err) {                         console.log(err)                    } else {                         res.render("page", {collection: collection, collection2: collection2});                    }                 });           }     });});

You can keep doing this infinitely but obviously this concept does not scale. If you had thirty different collections to pass through, this would be a really inconvenient way to do so.

From the research I've done, this is not as simple as it should be because the Collection.find() method is actually a Promise function. If it wasn't a promise function, we could simply just run the find() method for each collection, pass the results into a global object, and pass the entire object through the render. You can't do this though because the global variable will be initialized and passed through the render before the promise function finishes. You end up passing an empty object through the render. I know this because I tried it.

I have no experience with Promise functions. I'm going to do some research on them and see if there is a way to structure your code to take advantage of the promise function and execute this task more "elegantly". But in the mean time, use my example above, as I believe it is the most intuitive way to accomplish this.


I'm with same problem, and now I know it has to do with the fact that you cannot res.render() twice. There's a solution some recommend: using socket.io.I'd like to know if there's another solution, in my case I want to get recipes and authors from 2 different mongoDB collections but I can't do it with only 1 res.render(), can't believe node.js + express + mongoose won't accomplish something that simple to do in let's say... LAMP.