Node.js 将一个Mongoose查询的结果用于另一个Mongoose查询
我正在节点中构建一个应用程序,并将Mongoose与CosmosDB一起使用。我想显示与登录用户关联的公司拥有的所有绘图 我有一个用户,来自Passport.js,我使用他的电子邮件查询数据库,以便返回他的公司。还不错 我遇到的问题是:一旦我有了他的公司,我想运行第二个查询,以获得属于它的所有绘图。这应该返回一个对象数组,但返回一个空数组 两个问题:Node.js 将一个Mongoose查询的结果用于另一个Mongoose查询,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我正在节点中构建一个应用程序,并将Mongoose与CosmosDB一起使用。我想显示与登录用户关联的公司拥有的所有绘图 我有一个用户,来自Passport.js,我使用他的电子邮件查询数据库,以便返回他的公司。还不错 我遇到的问题是:一旦我有了他的公司,我想运行第二个查询,以获得属于它的所有绘图。这应该返回一个对象数组,但返回一个空数组 两个问题: 如何使当前代码正常工作 目前的结构非常笨拙,我如何使它更优雅 代码: 实际上,为了使它更优雅,你应该使用承诺,比如说库(或任何其他首选) 因此,当
实际上,为了使它更优雅,你应该使用承诺,比如说库(或任何其他首选) 因此,当您需要mongoose时,请为其提供一个Promise库,代码应该看起来更好,更具可读性和顺序性
const mongoose = require('mongoose');
const Promise = require('bluebird');
mongoose.Promise = Promise;
app.get('/plots', requireAuth,
function(req, res) {
User.find({ email: req.user.email }).lean()
.then(function(results) {
if (!results) throw new Error('User not found');
else return results[0].company;
})
.then(function(company) {
return PlotCast.find({ owner: company }).lean();
})
.then(function(results) {
if (!results) throw new Error('Plot Cast not found')
else {
console.log('results', results);
res.send(results);
}
})
.catch(function(e) {
console.log('error', e);
res.status(400).send(e);
});
})
实际上,为了使它更优雅,你应该使用承诺,比如说库(或任何其他首选) 因此,当您需要mongoose时,请为其提供一个Promise库,代码应该看起来更好,更具可读性和顺序性
const mongoose = require('mongoose');
const Promise = require('bluebird');
mongoose.Promise = Promise;
app.get('/plots', requireAuth,
function(req, res) {
User.find({ email: req.user.email }).lean()
.then(function(results) {
if (!results) throw new Error('User not found');
else return results[0].company;
})
.then(function(company) {
return PlotCast.find({ owner: company }).lean();
})
.then(function(results) {
if (!results) throw new Error('Plot Cast not found')
else {
console.log('results', results);
res.send(results);
}
})
.catch(function(e) {
console.log('error', e);
res.status(400).send(e);
});
})
有一个替代方案从来都不坏 我个人讨厌直接用承诺来工作,更喜欢用承诺。在您的情况下,这将非常有用,因为您基本上将结果从一个异步任务传递到下一个异步任务
app.get('/plots', requireAuth, function(req, res) {
async.waterfall([
function getUser(done) {
// use findOne, not find -- as you only want to retrive ONE user; using find is more expensive
User.findOne({ email: req.user.email }).lean().exec(done);
},
function getCasts(user, done) {
PlotCast.find({ owner: user.company }).lean().exec(done);
},
], function (err, casts) {
// if an error occurs during the above tasks ^, it will come down here
if (err) {
console.log(err);
return res.status(400).send(e);
}
// otherwise if all tasks finish, it will come down here
res.json(casts);
});
});
因此,使用async.js的好处是,您可以将所有错误集中在一个位置,而不是多个位置(这也可以根据您的操作而定)
我认为您最初的问题是您同时使用回调和承诺。通常你会使用其中一种方法。有一种替代的解决方案从来都不坏 我个人讨厌直接用承诺来工作,更喜欢用承诺。在您的情况下,这将非常有用,因为您基本上将结果从一个异步任务传递到下一个异步任务
app.get('/plots', requireAuth, function(req, res) {
async.waterfall([
function getUser(done) {
// use findOne, not find -- as you only want to retrive ONE user; using find is more expensive
User.findOne({ email: req.user.email }).lean().exec(done);
},
function getCasts(user, done) {
PlotCast.find({ owner: user.company }).lean().exec(done);
},
], function (err, casts) {
// if an error occurs during the above tasks ^, it will come down here
if (err) {
console.log(err);
return res.status(400).send(e);
}
// otherwise if all tasks finish, it will come down here
res.json(casts);
});
});
因此,使用async.js的好处是,您可以将所有错误集中在一个位置,而不是多个位置(这也可以根据您的操作而定)
我认为您最初的问题是您同时使用回调和承诺。通常使用其中一个。在第一次查询中使用
findOne()
。我通常通过使用async.js来避免回调地狱(在您的例子中,async.瀑布()会很有用)。第一个查询运行正常,问题出在第二个查询上。您不能只使用req.user
对象而不必再次查询集合吗?如果没有company
字段,那么当您使用passport.Ah-right-in-passport.js将用户序列化到会话中时,您可以填充该字段,我将像这样返回一个用户:return done(null,user)代码>,并且应该有关联的公司。但事实并非如此。如何添加此属性?请参阅在第一次查询中使用findOne()
。我通常通过使用async.js来避免回调地狱(在您的例子中,async.瀑布()会很有用)。第一个查询运行正常,问题出在第二个查询上。您不能只使用req.user
对象而不必再次查询集合吗?如果没有company
字段,那么当您使用passport.Ah-right-in-passport.js将用户序列化到会话中时,您可以填充该字段,我将像这样返回一个用户:return done(null,user)代码>,并且应该有关联的公司。但事实并非如此。如何添加此属性?请参见两个问题:1)您错误地要求了Bluebird两次?2) 我使用let company
的唯一原因是提供了一个变量,可以存储用户查询返回的数据。在您的示例中,我们正在查询PlotCast以查找所有者为公司变量的对象,但实际上从未将公司设置为等于任何值。在第一次查询中,这种情况不知何故发生了吗?1)抱歉,是的,我错误地要求了它,将更新2)公司
是从以前的中返回的。然后()
在中返回结果[0]。公司
对,我知道我们返回结果[0]。公司
,但这只是第一个结果中keycompany
对应的值。我们从来没有将变量company设置为等于这个回报,对吗?哦,对,我们只是从以前的承诺和使用中返回它。如果您需要将值存储在公司
代码中的某个位置,而不仅仅是向PlotCast
发出请求,那么您肯定可以将该值存储在公司
中,因为这是一种标准的承诺机制,当我从上一个语句返回某个值时,它将被传递到下一个语句。我将删除让公司
,以避免误解。如果你愿意,我们可以继续聊天,但我似乎缺少20点信誉点:)两个问题:1)你错误地要求了蓝鸟两次?2) 我使用let company
的唯一原因是提供了一个变量,可以存储用户查询返回的数据。在您的示例中,我们正在查询PlotCast以查找所有者为公司变量的对象,但实际上从未将公司设置为等于任何值。在第一次查询中,这种情况不知何故发生了吗?1)抱歉,是的,我错误地要求了它,将更新2)公司
是从以前的中返回的。然后()
在中返回结果[0]。公司
对,我知道我们返回结果[0]。公司
,但这只是第一个结果中keycompany
对应的值。我们从来没有将变量company设置为等于这个回报,对吗?哦,对,我们只是从以前的承诺和使用中返回它。如果您需要将值存储在代码中的某个位置,而不只是请求PlotCast
它知道,您完全可以将该值存储在公司中