Node.JS, Express & MongoDB :: Multiple Collections

I use Node.JS, Express, MongoDB and EJS. I have a question about several MongoDB collections under the same database and calling them for use in the interface. I have 3 collections, and after many studies I could not find how to call several collections without errors.

I understand that it would be unimportant to keep everything under one collection, but I believe that the best approach is to separate them into categories. Here is my db / collection call:

app.use(express.bodyParser()); var MongoClient = require('mongodb').MongoClient; app.get('/', function(req, res){ MongoClient.connect("mongodb://localhost:27017/michael", function(err, db) { if(!err) { console.log("We are connected"); } db.collection("portfolio", function(err, collection) { collection.find().sort({order_num: 1}).toArray(function(err, result) { var portfolio = []; if (err) { throw err; } else { for (i=0; i<result.length; i++) { portfolio[i] = result[i]; } res.render('index.html', {portfolio: portfolio}); } }); }); }); }); 

How can I make some calls for additional collections, such as the "about" collection, etc.? I tried adding more ...

 db.collection("about", function(err, collection) { 

... in...

 MongoClient.connect("mongodb://localhost:27017/michael", function(err, db) { 

... but it gives me errors in the terminal console log.

Thanks in advance.

EDIT:

Here is what I am trying to do that gives me an error:

 app.get('/', function(req, res){ MongoClient.connect("mongodb://localhost:27017/michael", function(err, db) { if(!err) { console.log("We are connected"); } db.collection("portfolio", function(err, collection) { collection.find().sort({order_num: 1}).toArray(function(err, result) { var portfolio = []; if (err) { throw err; } else { for (i=0; i<result.length; i++) { portfolio[i] = result[i]; } res.render('index.html', {portfolio: portfolio}); } }); }); // Here the additional collection call: db.collection("about", function(err, collection) { collection.find().sort({order_num: 1}).toArray(function(err, result) { var about = []; if (err) { throw err; } else { for (i=0; i<result.length; i++) { about[i] = result[i]; } res.render('index.html', {about: about}); } }); }); }); }); 

Here's the error from the console:

 ReferenceError: /Volumes/Files/WebDev/RHC/michael/michael/views/index.html:62 60| <div class="row-fluid"> 61| <ul id="work" class="thumbnails"> >> 62| <% for(i=0; i<portfolio.length; i++) { %> 63| <% if (portfolio[i].proj_type == "work") { %> 64| <% var newLine = ""; %> 65| <% var fancyBox = ""; %> portfolio is not defined 

So, I have two collections in MongoDB under db called "michael", and I'm trying to call them both under the same MongoClient.connect (). Then I send the results to the front-end (via EJS) in two arrays: "portfolio" and "o". It seems that when I do this, it displays the "portfolio" undefined. Hope this makes sense.

+6
source share
5 answers

Well, using the aesede solution plus my own messing around, I got it to display two collections. This may probably be useful, but here is what I got:

 // GLOBAL ARRAYS FOR STORING COLLECTION DATA var 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 error, by itself, that I discovered was that when Node rebooted and I clicked "refresh" in the browser, I did not see the content being displayed in HTML. However, any subsequent update showed the content sequentially.

+6
source

I have the same problem and now I know that this is because you cannot res.render () twice. There is a solution recommending: socket.io . I would like to know if there is another solution, in my case I want to get recipes and authors from two different mongoDB collections, but I can not do this with only 1 res.render (), I can not believe node. js + express + mongoose will not do something that is simple to do, let it say ... LAMP.

0
source
 app.get("/customer",function(req,res) { var orders={}; //Create Empty order Object var products={}; //Create Empty product Object Product.find({},function (err,allproducts) { if (err) { console.log(err); } else { //Find Collection And Assign It To Object products=allproducts; } }); Order.find({}).sort({"date":'desc'}).exec(function(err, allOrders) { if (err) { console.log(err); } else { //find order collection and sort it in desending order and assign it to order object orders=allOrders; res.render("./customer/dashboard",{products:products , orders:orders}); } }); }); 

I faced the same problem, I solved it using the above mechanism. I recommend using empty objects instead of arrays, since MongoDb returns an object, and you may also encounter some type errors when using arrays instead of objects

0
source

Your answer fits perfectly with my project. But I can not get the data in the ejs sheet. But when I tested with locus, I can see all the data received from the database before the page displays. If it comes to res.render (), why is it not passed to the ejs template.

 const vendorSchema = new mongoose.Schema({ name:String, image:String, imageId:String, promotionv:[{ type:mongoose.Schema.Types.ObjectId, ref:'Promotion' }] }); const newpromoSchema = new mongoose.Schema({ name:String, image:String, imageId:String, vendor:String, description:String, sdate:String, edate:String, }); router.get("/vendors/:id",function(req,res) { var events={}; //Create Empty event Object var promotions={}; //Create Empty promotion Object var vendors={};//Create Empty vendor Objext Promotion.find({},function (err,allPromotions) { if (err) { console.log(err); } else { //Find Collection And Assign It To Object promotions=allPromotions; } }); Event.find({},function(err, allEvents) { if (err) { console.log(err); } else { events=allEvents; } }); Vendor.find({},function(err,allVendors){ if(err){ console.log(err); }else{ vendors=allVendors; //find order collection and passing it to ejs templates res.render("vendors/show",{ event:events, promotion:promotions vendor:vendors}); } }); }); Show.ejs code as <%=vendor.name%> <%=promotion.name%> <%=event.name%> 
0
source

Actually there is a really simple, intuitive answer to this problem. This is definitely not elegant, and I think the update for Express, Mongoose, and NodeJS should include a predefined way to do this, and not think through the process logically.

All you have to do is insert your find () calls into each other for each collection you want to pass 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 continue to do this indefinitely, but it is obvious that this concept does not scale. If you had to go through thirty different collections, it would be very inconvenient.

From my research, this is not as simple as it should be, because the Collection.find () method is actually a Promise function. If this were not a promise function, we could just run the find () method on each collection, pass the results to the global object, and pass the entire object through a render. You cannot do this because the global variable will be initialized and passed through the render until the promise function is completed. As a result, you pass an empty object through a render. I know this because I tried it.

I have no experience with Promise features. I'm going to research them and see if there is a way to structure your code in order to take advantage of the promise function and complete this task more "elegantly." But for now, use my example above, as I believe this is the most intuitive way to do this.

0
source

Source: https://habr.com/ru/post/1497668/


All Articles