[英]Node.JS, Express & MongoDB Atlas:: Multiple Collections ejs
[英]Node.JS, Express & MongoDB :: Multiple Collections
我正在使用 Node.JS、Express、MongoDB 和 EJS。 我有一个关于一个数据库下的多个 MongoDB 集合的问题,并调用它们在前端使用。 我有 3 个集合,经过大量研究还没有找到如何正确调用多个集合。
我知道将所有内容存储在一个集合中不会有问题,但我觉得最好的方法是按类别将它们分开。 这是我的 db/collection 电话:
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});
}
});
});
});
});
如何多次调用其他集合,例如“关于”集合等? 我尝试添加另一个...
db.collection("about", function(err, collection) {
...之内...
MongoClient.connect("mongodb://localhost:27017/michael", function(err, db) {
...但它在终端控制台日志中给了我错误。
提前致谢。
编辑:
这是我想要做的,这给了我一个错误:
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's 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});
}
});
});
});
});
这是来自控制台的错误:
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
因此,我在 MongoDB 中名为“michael”的数据库下有两个集合,我试图在一个 MongoClient.connect() 下调用它们。 然后我将结果以两个数组发送到前端(通过 EJS):“portfolio”和“about”。 似乎当我这样做时,它使“投资组合”未定义。 希望这是有道理的。
好的,使用 aesede 的解决方案加上我自己的修补,我得到了它来渲染两个集合。 它可能会使用一些技巧,但这是我得到的:
// 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
});
});
});
});
我发现的唯一错误是,当 Node 重新启动并在浏览器中点击“刷新”时,我没有看到任何内容在 HTML 中呈现。 但是,任何后续刷新都会始终如一地显示内容。
对于这个问题,实际上有一个非常简单、直观的答案。 这绝对不优雅,我确实认为对 Express、Mongoose 和 NodeJS 的更新应该包含一种预设的方式来做到这一点,而不必从逻辑上思考这个过程。
您所要做的就是为要传递到页面的每个集合将您的 find() 调用相互嵌套。 下面的例子:
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});
}
});
}
});
});
你可以无限地这样做,但显然这个概念不能扩展。 如果您有 30 个不同的集合要通过,这将是一种非常不方便的方式。
从我所做的研究来看,这并不像它应该的那么简单,因为 Collection.find() 方法实际上是一个 Promise 函数。 如果它不是一个 promise 函数,我们可以简单地为每个集合运行 find() 方法,将结果传递给一个全局对象,然后通过渲染传递整个对象。 但是你不能这样做,因为全局变量将在 promise 函数完成之前被初始化并通过渲染。 您最终通过渲染传递了一个空对象。 我知道这是因为我试过了。
我对 Promise 函数没有经验。 我将对它们进行一些研究,看看是否有一种方法可以构建您的代码以利用 promise 函数并更“优雅地”执行此任务。 但同时,请使用我上面的示例,因为我认为这是实现此目的的最直观的方法。
我有同样的问题,现在我知道这与你不能 res.render() 两次的事实有关。 有人推荐了一个解决方案:使用socket.io 。 我想知道是否有另一种解决方案,在我的情况下,我想从 2 个不同的 mongoDB 集合中获取食谱和作者,但我无法仅使用 1 个 res.render() 来完成,无法相信 node.js + express + mongoose 不会完成这么简单的事情,比如说...... LAMP。
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});
}
});
});
我遇到了同样的问题,我用上述机制解决了它我建议使用空对象而不是数组作为 MongoDb 返回对象,而且当您使用数组而不是对象时,您可能会遇到一些类型错误
function mongoConnection() {
return new Promise((res, rej) => {
try {
MongoClient.connect(conn_url, {},
function (err, client) {
if (err) { res(false); }
else {
promise_db_connection = new Promise((resolve, reject) => {
var db = client.db(Database);
resolve(
{
'collection_1': db.collection("collection_1"),
'collection_2': db.collection("collection_2"),
'collection_3': db.collection("collection_3")
}
);
res(true);
});
}
}
);
} catch (error) {
res(false);
}
})
}
mongoConnection().then((result) => {
console.log(result ? 'Connection Successful' : 'Connection Failed');
})
app.get('/customer', (req, res) => {
var product = [], order = []
promise_db_connection.then((result) => {
result.collection_1.find({}).toArray((err, data) => {
if (!err) product = data;
result.collection_2.find({}).toArray((err, data) => {
if (!err) order = data;
})
res.render("page", { product: product, order: order });
})
})
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.