Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 将一个Mongoose查询的结果用于另一个Mongoose查询_Node.js_Mongodb_Mongoose - Fatal编程技术网

Node.js 将一个Mongoose查询的结果用于另一个Mongoose查询

Node.js 将一个Mongoose查询的结果用于另一个Mongoose查询,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我正在节点中构建一个应用程序,并将Mongoose与CosmosDB一起使用。我想显示与登录用户关联的公司拥有的所有绘图 我有一个用户,来自Passport.js,我使用他的电子邮件查询数据库,以便返回他的公司。还不错 我遇到的问题是:一旦我有了他的公司,我想运行第二个查询,以获得属于它的所有绘图。这应该返回一个对象数组,但返回一个空数组 两个问题: 如何使当前代码正常工作 目前的结构非常笨拙,我如何使它更优雅 代码: 实际上,为了使它更优雅,你应该使用承诺,比如说库(或任何其他首选) 因此,当

我正在节点中构建一个应用程序,并将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]。公司
    ,但这只是第一个结果中key
    company
    对应的值。我们从来没有将变量company设置为等于这个回报,对吗?哦,对,我们只是从以前的承诺和使用中返回它。如果您需要将值存储在
    公司
    代码中的某个位置,而不仅仅是向
    PlotCast
    发出请求,那么您肯定可以将该值存储在
    公司
    中,因为这是一种标准的承诺机制,当我从上一个
    语句返回某个值时,它将被传递到下一个
    语句。我将删除
    让公司
    ,以避免误解。如果你愿意,我们可以继续聊天,但我似乎缺少20点信誉点:)两个问题:1)你错误地要求了蓝鸟两次?2) 我使用
    let company
    的唯一原因是提供了一个变量,可以存储用户查询返回的数据。在您的示例中,我们正在查询PlotCast以查找所有者为公司变量的对象,但实际上从未将公司设置为等于任何值。在第一次查询中,这种情况不知何故发生了吗?1)抱歉,是的,我错误地要求了它,将更新2)
    公司
    是从以前的
    中返回的。然后()
    中返回结果[0]。公司
    对,我知道我们
    返回结果[0]。公司
    ,但这只是第一个结果中key
    company
    对应的值。我们从来没有将变量company设置为等于这个回报,对吗?哦,对,我们只是从以前的承诺和使用中返回它。如果您需要将值存储在代码中的某个位置,而不只是请求
    PlotCast
    它知道
    ,您完全可以将该值存储在
    公司中