8

我正在使用 Node.JS、Express、MongoDB 和 EJS。我有一个关于一个数据库下的多个 MongoDB 集合的问题,并调用它们在前端使用。我有 3 个集合,经过大量研究,还没有找到如何调用多个集合而不会出错。

我知道将所有内容存储在一个集合中不会有问题,但我觉得最好的方法是按类别将它们分开。这是我的数据库/集合调用:

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

所以我在名为“michael”的数据库下的 MongoDB 中有两个集合,我试图在一个 MongoClient.connect() 下调用它们。然后,我将结果以两个数组的形式(通过 EJS)发送到前端:“portfolio”和“about”。似乎当我这样做时,它会使“投资组合”未定义。希望这是有道理的。

4

5 回答 5

7

好的,使用 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 中呈现的任何内容。但是,任何后续刷新都会一致地显示内容。

于 2013-10-07T02:30:38.307 回答
2

这个问题实际上有一个非常简单、直观的答案。这绝对不是优雅的,我确实认为对 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 函数并更“优雅地”执行此任务。但与此同时,请使用我上面的示例,因为我相信这是完成此操作的最直观的方法。

于 2019-08-15T20:32:37.000 回答
0

我有同样的问题,现在我知道这与你不能 res.render() 两次的事实有关。有人推荐一个解决方案:使用socket.io。我想知道是否有另一种解决方案,就我而言,我想从 2 个不同的 mongoDB 集合中获取食谱和作者,但我不能只用 1 个 res.render() 来做到这一点,不敢相信 node.js + express + mongoose 不会完成那么简单的事情,比如说...... LAMP。

于 2013-09-26T00:08:28.337 回答
0
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 返回对象,而且当你使用数组而不是对象时,你可能会遇到一些类型错误

于 2018-01-22T12:14:56.193 回答
0
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 });
        })

    })
})
于 2021-06-07T09:12:21.720 回答