如何使用mongoose查询和async-await / Promise访问/返回mongo文档中的值?

时间:2019-01-03 13:21:24

标签: node.js mongodb mongoose promise async-await

我曾经使用过mongoDB,但是我是Node.js和mongoose的新手,我正试图了解如何在async-await / Promises中使用mongoose。我正在创建一个具有Web套接字(socket.io)应用程序的React / Node,用户可以在其中创建一个帐户并登录(如果已经拥有一个帐户)。我已经能够成功创建和执行mongo / mogoose查询,但是一旦获得文档,我在使用文档时会遇到问题。这是我的代码:

const profileRoute = (action, io) => {
    switch (action.cmd) {
        case 'LOGIN':
            getProfile(action.email)
                .then(profile => {
                    console.log('profile: ', profile)     // prints the mongo document properly.
                    console.log('email: ', profile.email) // email: undefined
                    io.emit('action', {
                        type: PROFILE_LOGIN,
                        email: profile.email,
                        name: profile.name,
                    });
                .catch(err => {console.log(err)});
            break;
        default:
            break;
    }
};

这是“ getProfile()”的样子:

export const getProfile = async (email) => {
    const tempPromise = collection.findOne({ email }).exec();
    try {
        return await tempPromise;
    } catch (err) {
        console.log(err);
        return {};
    } 
};

我也试图简化“ getProfile()”的含义,因为异步等待在这里无济于事(只是想尝试一些小小的入门),

export const getProfile = (email) => {
    return collection.findOne({ email }).exec();
};

但是无论哪种方式,当我打印“ profile.email”时,它都是未定义的,并且我的结果来自

io.emit('action', {
    type: PROFILE_LOGIN,
    email: profile.email,
    name: profile.name,
});

是:

{
    type: PROFILE_LOGIN,
}

但是如果我这样做:

io.emit('action', {
    type: PROFILE_LOGIN,
    profile: profile,
});

结果是:

{
    type: PROFILE_LOGIN,
    profile: {correct mongo document},
}

但是我只需要/想要mongo文档中的一些值。

此外,如果有使用async-await重写“ profileRoute()”(我知道这个问题不是真的)的更好方法,我愿意提出建议。

编辑:当我最初写这个问题时有一个错字。已更改:

{
    type: PROFILE_LOGIN,
    profile: [correct mongo document],
}

这更准确地反映了“ .findOne()”的回报:

{
    type: PROFILE_LOGIN,
    profile: {correct mongo document},
}

2 个答案:

答案 0 :(得分:1)

const profileRoute = async (action, io) => {
  switch (action.cmd) {
    case 'LOGIN':
      try {
        const profile = await getProfile(action.email);
        if (!profile) {
          throw new Error(`Profile with email ${action.email} not found`);
        }
        io.emit('action', {
          type: PROFILE_LOGIN,
          email: profile.email,
          name: profile.name
        });
      } catch (e) {
        console.log(e);
      }
      break;
    default:
      break;
  }
};

您的getProfile()代码就是:

export const getProfile = email => {
  return collection.findOne({ email }).exec();
};

答案 1 :(得分:-1)

export const getProfile = async (email) => {
    const tempPromise = collection.findOne({ email }).exec();
    try {
        return await tempPromise;
    } catch (err) {
        console.log(err);
        return {};
    }  };

您应该在collection.findOne前面添加一个等待 而且,如果您只想获取json对象,则可以像这样在猫鼬查询的末尾添加lean()。

export const getProfile = async (email) => {
    const tempPromise = await collection.findOne({ email }).lean().exec();
    try {
        return await tempPromise;
    } catch (err) {
        console.log(err);
        return {};
    } 
};