如何使用Express从MongoDB聚合两个集合?

时间:2019-10-02 21:22:11

标签: mongodb express mern

所以我目前有两个收藏。一个是“帖子”,另一个是“用户”

这是帖子:

  • _id
  • 标题
  • 文本
  • 用户
  • 日期

这是用户:

  • _id
  • 用户名
  • 电子邮件
  • 密码

我正尝试通过以下方式使用聚合:

router.get('/:user_id', async (req, res) => {
  try {
    // const profile = await User.findById(req.params.user_id);
    const profile = await User.agregate([
      {
        '$lookup': {
          'from': 'posts',
          'localField': '_id',
          'foreignField': 'user',
          'as': 'posts'
        }
      }
    ]);

    // Verify profile exists
    if (!profile) return res.status(400).json({ msg: 'Profile not found' });

    res.json(profile);
  } catch (err) {
    console.error(err.message);
    if (err.kind == 'ObjectId') {
      return res.status(400).json({ msg: 'Profile not found' });
    }
    res.status(500).send('Server error');
  }
});

请注意,第一个配置文件常量已注释,但这是我用来根据X用户的_id( req.params.user_id )提取用户数据的常量。

现在我要创建的是通过访问X用户的个人资料来显示X用户创建的所有帖子,因此我需要匹配相应的用户,我需要传递 req.params.user_id < / strong>。

这是我无法使用的新代码:

router.get('/:user_id', async (req, res) => {
  try {
    // const profile = await User.findById(req.params.user_id);
    const profile = await User.agregate([
      {
        '$lookup': {
          'from': 'posts',
          'localField': '_id',
          'foreignField': 'user',
          'as': 'posts'
        }
      }, {
        $unwind: "$posts"
      }, {
        $match: {
          "posts.user": req.params.user_id
        }
      }
    ]);

    // Verify profile exists
    if (!profile) return res.status(400).json({ msg: 'Profile not found' });

    res.json(profile);
  } catch (err) {
    console.error(err.message);
    if (err.kind == 'ObjectId') {
      return res.status(400).json({ msg: 'Profile not found' });
    }
    res.status(500).send('Server error');
  }
});

在console.log中显示的错误是“ user.aggregate不是函数”。希望我能解释自己,谢谢!。

我只想在用户集合中添加一个新字段(帖子数组)。

1 个答案:

答案 0 :(得分:0)

如果有人像我一样达到了相同的要求,这就是经过两天的研究和询问后的解决方案。

router.get('/:user_id', async (req, res) => {
  try {
    const userId = req.params.user_id;
    const [profile, postsByUser] = await Promise.all([User.findById(userId, '-password'), Post.find({ user: userId }).populate('user', ['_id', 'username', 'avatar']).sort({ date: -1 })]);

    // Verify profile exists
    if (!profile) return res.status(400).json({ msg: 'Profile not found' });

    // res.json(profile);
    res.json({ ...profile.toJSON(), postsByUser });
  } catch (err) {
    console.error(err.message);
    if (err.kind == 'ObjectId') {
      return res.status(400).json({ msg: 'Profile not found' });
    }
    res.status(500).send('Server error');
  }
});